create export file if not exists

This commit is contained in:
brevalferrari 2025-06-05 17:39:37 +02:00
parent e9fcec8b32
commit da38edbfd1

View file

@ -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,