use clap::{Parser, Subcommand};
#[derive(Subcommand, Debug)]
pub enum CliCommands {
Open {
#[arg()]
file: Option<String>,
},
Info {
#[arg(short, long)]
file: Option<String>,
},
Export {
#[arg(short, long)]
file: Option<String>,
#[arg(short = 'F', long)]
format: String,
#[arg(short, long)]
output: String,
},
}
#[derive(Parser, Debug)]
#[command(name = "mcraw-tui", about = "Cross-platform TUI for MotionCam .mcraw files")]
pub struct Cli {
#[arg(short, long)]
pub file: Option<String>,
#[command(subcommand)]
pub command: Option<CliCommands>,
#[arg(short = 'n', long)]
pub frames: Option<usize>,
#[arg(long)]
pub placeholder_path: Option<String>,
#[arg(short, long, global = true)]
pub verbose: bool,
#[arg(short, long)]
pub output: Option<String>,
}
impl Cli {
pub fn resolve(self) -> ResolvedCli {
match self.command {
Some(cmd) => ResolvedCli::Command(cmd.resolve_with_top_level(self.file)),
None => {
if let Some(ref file) = self.file {
ResolvedCli::Command(CliCommands::Open { file: Some(file.clone()) })
} else {
ResolvedCli::NoFile
}
}
}
}
pub fn validate_export_format(format: &str) -> Result<(), String> {
let valid = ["dng", "prores", "h264", "hevc"];
let lower = format.to_lowercase();
if valid.contains(&lower.as_str()) {
Ok(())
} else {
Err(format!(
"Invalid export format '{}'. Valid formats: {}",
format,
valid.join(", ")
))
}
}
}
impl CliCommands {
fn resolve_with_top_level(self, top_level_file: Option<String>) -> Self {
match self {
CliCommands::Open { file } => CliCommands::Open {
file: file.or(top_level_file),
},
CliCommands::Info { file } => CliCommands::Info {
file: file.or(top_level_file),
},
CliCommands::Export { file, format, output } => CliCommands::Export {
file: file.or(top_level_file),
format,
output,
},
}
}
}
pub enum ResolvedCli {
Command(CliCommands),
NoFile,
}