use clap::{Parser, Subcommand};
use ratatui::style::Color;
use crate::music::Note;
const HELP_TEMPLATE: &str = "{before-help}\
{name} {version} -- by {author}
{about}
{usage-heading} {usage}
{all-args}{after-help}
";
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None, help_template = HELP_TEMPLATE)]
pub struct ScopeArgs {
#[clap(subcommand)]
pub source: ScopeSource,
#[command(flatten)]
pub opts: SourceOptions,
#[command(flatten)]
pub ui: UiOptions,
}
#[derive(Debug, Clone, Parser)]
pub struct UiOptions {
#[arg(short, long, value_name = "x", default_value_t = 1.0)]
pub scale: f32,
#[arg(long, default_value_t = false)]
pub scatter: bool,
#[arg(long, default_value_t = false)]
pub no_reference: bool,
#[arg(long, default_value_t = false)]
pub no_ui: bool,
#[arg(long, default_value_t = false)]
pub no_braille: bool,
#[arg(long, value_name = "color1,color2", value_delimiter = ',', default_value = "red,yellow,cyan,magenta")]
pub palette_color: Vec<Color>,
#[arg(long, value_name = "color", default_value_t = Color::Cyan)]
pub labels_color: Color,
#[arg(long, value_name = "color", default_value_t = Color::DarkGray)]
pub axis_color: Color,
}
#[derive(Debug, Clone, Subcommand)]
pub enum ScopeSource {
#[cfg(feature = "pulseaudio")]
Pulse {
device: Option<String>,
#[arg(long, value_name = "N", default_value_t = 32)]
server_buffer: u32,
},
#[cfg(feature = "file")]
File {
path: String,
#[arg(short, long, default_value_t = false)]
limit_rate: bool,
},
#[cfg(feature = "cpal")]
Audio {
device: Option<String>,
#[arg(long, default_value_t = 5)]
timeout: u64,
#[arg(long, default_value_t = false)]
list: bool,
},
}
#[derive(Debug, Clone, Parser)]
pub struct SourceOptions {
#[arg(short, long, value_name = "N", default_value_t = 2)]
pub channels: usize,
#[arg(short, long, value_name = "SIZE", default_value_t = 2048)]
pub buffer: u32,
#[arg(short = 'r', long, value_name = "HZ", default_value_t = 48000)]
pub sample_rate: u32,
#[arg(short, long, value_name = "NOTE")]
pub tune: Option<String>,
}
impl SourceOptions {
pub fn tune(&mut self) {
if let Some(txt) = &self.tune {
if let Ok(note) = txt.parse::<Note>() {
self.buffer = note.tune_buffer_size(self.sample_rate);
while self.buffer.is_multiple_of(self.channels as u32 * 2) {
self.buffer += 1; }
} else {
eprintln!("[!] Unrecognized note '{}', ignoring option", txt);
}
}
}
}