1use clap::{Parser, Subcommand};
2
3use crate::music::Note;
4
5const HELP_TEMPLATE : &str = "{before-help}\
6{name} {version} -- by {author}
7{about}
8
9{usage-heading} {usage}
10
11{all-args}{after-help}
12";
13
14#[derive(Parser, Debug)]
16#[command(author, version, about, long_about = None, help_template = HELP_TEMPLATE)]
17pub struct ScopeArgs {
18 #[clap(subcommand)]
19 pub source: ScopeSource,
20
21 #[command(flatten)]
22 pub opts: SourceOptions,
23
24 #[command(flatten)]
25 pub ui: UiOptions,
26}
27
28#[derive(Debug, Clone, Parser)]
29pub struct UiOptions {
30 #[arg(short, long, value_name = "x", default_value_t = 1.0)]
32 pub scale: f32,
33
34 #[arg(long, default_value_t = false)]
36 pub scatter: bool,
37
38 #[arg(long, default_value_t = false)]
40 pub no_reference: bool,
41
42 #[arg(long, default_value_t = false)]
44 pub no_ui: bool,
45
46 #[arg(long, default_value_t = false)]
48 pub no_braille: bool,
49}
50
51#[derive(Debug, Clone, Subcommand)]
52pub enum ScopeSource {
53
54 #[cfg(feature = "pulseaudio")]
55 Pulse {
57 device: Option<String>,
59
60 #[arg(long, value_name = "N", default_value_t = 32)]
62 server_buffer: u32,
63 },
64
65 #[cfg(feature = "file")]
66 File {
68 path: String,
70
71 #[arg(short, long, default_value_t = false)]
73 limit_rate: bool,
74 },
75
76 #[cfg(feature = "cpal")]
77 Audio {
79 device: Option<String>,
81
82 #[arg(long, default_value_t = 60)]
84 timeout: u64,
85
86 #[arg(long, default_value_t = false)]
88 list: bool,
89 }
90}
91
92#[derive(Debug, Clone, Parser)]
93pub struct SourceOptions {
94 #[arg(long, value_name = "N", default_value_t = 2)]
96 pub channels: usize,
97
98 #[arg(short, long, value_name = "SIZE", default_value_t = 2048)]
100 pub buffer: u32,
101
102 #[arg(long, value_name = "HZ", default_value_t = 48000)]
104 pub sample_rate: u32,
105
106 #[arg(long, value_name = "NOTE")]
108 pub tune: Option<String>,
109}
110
111impl SourceOptions {
113 pub fn tune(&mut self) {
114 if let Some(txt) = &self.tune { if let Ok(note) = txt.parse::<Note>() {
116 self.buffer = note.tune_buffer_size(self.sample_rate);
117 while self.buffer % (self.channels as u32 * 2) != 0 { self.buffer += 1; }
120 } else {
121 eprintln!("[!] Unrecognized note '{}', ignoring option", txt);
122 }
123 }
124 }
125}