create export file if not exists
This commit is contained in:
parent
e9fcec8b32
commit
da38edbfd1
1 changed files with 26 additions and 13 deletions
|
@ -49,7 +49,7 @@ pub(super) enum Cli {
|
||||||
pub(super) struct PlayOpts {
|
pub(super) struct PlayOpts {
|
||||||
/// Use this sheet music [default: stdin]
|
/// Use this sheet music [default: stdin]
|
||||||
#[command(flatten)]
|
#[command(flatten)]
|
||||||
input: InputGroup,
|
input: InputGroup<false>,
|
||||||
/// Set available notes ("a,b,c" for example)
|
/// Set available notes ("a,b,c" for example)
|
||||||
#[arg(short, long, value_delimiter = ',')]
|
#[arg(short, long, value_delimiter = ',')]
|
||||||
notes: Vec<String>,
|
notes: Vec<String>,
|
||||||
|
@ -89,7 +89,10 @@ impl PlayOpts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputGroup {
|
impl<const CREATE_IF_NOT_EXISTS: bool> InputGroup<CREATE_IF_NOT_EXISTS>
|
||||||
|
where
|
||||||
|
Self: Clone,
|
||||||
|
{
|
||||||
pub(super) fn get(&self) -> Box<dyn Read> {
|
pub(super) fn get(&self) -> Box<dyn Read> {
|
||||||
self.input
|
self.input
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -215,34 +218,44 @@ where
|
||||||
|
|
||||||
#[derive(Debug, Parser, Clone)]
|
#[derive(Debug, Parser, Clone)]
|
||||||
#[group(required = false, multiple = false)]
|
#[group(required = false, multiple = false)]
|
||||||
pub(super) struct InputGroup {
|
pub(super) struct InputGroup<const CREATE_IF_NOT_EXISTS: bool> {
|
||||||
/// Set the path to your sheet music file [default: stdin]
|
/// Set the path to your sheet music file [default: stdin]
|
||||||
input: Option<ClonableFile>,
|
input: Option<ClonableFile<CREATE_IF_NOT_EXISTS>>,
|
||||||
/// Use this sheet music instead of reading from a file or stdin
|
/// Use this sheet music instead of reading from a file or stdin
|
||||||
#[arg(short = 'c')]
|
#[arg(short = 'c')]
|
||||||
sheet_music_string: Option<String>,
|
sheet_music_string: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct ClonableFile(File);
|
pub(super) struct ClonableFile<const CREATE_IF_NOT_EXISTS: bool>(File);
|
||||||
|
|
||||||
impl Clone for ClonableFile {
|
impl<const CREATE_IF_NOT_EXISTS: bool> Clone for ClonableFile<CREATE_IF_NOT_EXISTS> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self(self.0.try_clone().expect("cloning file handle"))
|
Self(self.0.try_clone().expect("cloning file handle"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for ClonableFile {
|
impl<const CREATE_IF_NOT_EXISTS: bool> FromStr for ClonableFile<CREATE_IF_NOT_EXISTS> {
|
||||||
type Err = io::Error;
|
type Err = io::Error;
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
File::open(s).map(Self)
|
match CREATE_IF_NOT_EXISTS {
|
||||||
|
true => File::create(s),
|
||||||
|
false => File::open(s),
|
||||||
|
}
|
||||||
|
.map(Self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<const CREATE_IF_NOT_EXISTS: bool> From<ClonableFile<CREATE_IF_NOT_EXISTS>> for File {
|
||||||
|
fn from(value: ClonableFile<CREATE_IF_NOT_EXISTS>) -> Self {
|
||||||
|
value.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Parser, Clone)]
|
#[derive(Debug, Parser, Clone)]
|
||||||
pub(super) struct ExportOpts {
|
pub(super) struct ExportOpts {
|
||||||
#[command(flatten)]
|
#[command(flatten)]
|
||||||
playopts: PlayOpts,
|
pub(super) playopts: PlayOpts,
|
||||||
/// Audio format to use
|
/// Audio format to use
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
feature = "mp3",
|
feature = "mp3",
|
||||||
|
@ -253,14 +266,14 @@ pub(super) struct ExportOpts {
|
||||||
cfg_attr(feature = "raw", arg(default_value = "raw mulaw"))
|
cfg_attr(feature = "raw", arg(default_value = "raw mulaw"))
|
||||||
)]
|
)]
|
||||||
#[arg(short, long, value_parser = audio_format_parser)]
|
#[arg(short, long, value_parser = audio_format_parser)]
|
||||||
format: AudioFormat,
|
pub(super) format: AudioFormat,
|
||||||
/// Output file [default: stdout]
|
/// Output file [default: stdout]
|
||||||
output: Option<ClonableFile>,
|
pub(super) output: Option<ClonableFile<true>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, EnumDiscriminants)]
|
#[derive(Clone, EnumDiscriminants)]
|
||||||
#[strum_discriminants(derive(EnumString, IntoStaticStr), strum(serialize_all = "lowercase"))]
|
#[strum_discriminants(derive(EnumString, IntoStaticStr), strum(serialize_all = "lowercase"))]
|
||||||
enum AudioFormat {
|
pub(super) enum AudioFormat {
|
||||||
Mp3 {
|
Mp3 {
|
||||||
bitrate: Bitrate,
|
bitrate: Bitrate,
|
||||||
quality: Quality,
|
quality: Quality,
|
||||||
|
@ -397,7 +410,7 @@ fn audio_format_parser(input: &str) -> Result<AudioFormat, anyhow::Error> {
|
||||||
|
|
||||||
#[derive(Debug, Parser, Clone, EnumString, Default)]
|
#[derive(Debug, Parser, Clone, EnumString, Default)]
|
||||||
#[strum(ascii_case_insensitive)]
|
#[strum(ascii_case_insensitive)]
|
||||||
enum RawAudioFormat {
|
pub(super) enum RawAudioFormat {
|
||||||
ALaw,
|
ALaw,
|
||||||
F32Be,
|
F32Be,
|
||||||
F32Le,
|
F32Le,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue