diff options
author | Fletcher Woodruff <fletcherw@chromium.org> | 2019-10-16 11:46:21 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-10-25 23:21:20 +0000 |
commit | 58df1c3f42565095f11c2bebe452128d69bbeb3d (patch) | |
tree | 7656de754321033b5664f459d4e1b20777a9706f /cras/client/cras_tests | |
parent | c156f5fe51c89849e12660fa107ed673f1809802 (diff) | |
download | adhd-58df1c3f42565095f11c2bebe452128d69bbeb3d.tar.gz |
CRAS: cras_tests: Restructure arguments
In preparation for adding control functionality to cras_tests,
restructure Command by making AudioOptions a parameter of the Command
enum, e.g Command::Capture(AudioOptions). This way, a control command
can be later added as Command::Control(ControlOptions).
BUG=chromium:1008990
TEST=cargo test
Change-Id: Ic341b78b2c6ea6e74baf776b95bb1134c0d4b2f6
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/adhd/+/1865832
Tested-by: Fletcher Woodruff <fletcherw@chromium.org>
Reviewed-by: Chih-Yang Hsia <paulhsia@chromium.org>
Commit-Queue: Fletcher Woodruff <fletcherw@chromium.org>
Diffstat (limited to 'cras/client/cras_tests')
-rw-r--r-- | cras/client/cras_tests/src/arguments.rs | 158 | ||||
-rw-r--r-- | cras/client/cras_tests/src/main.rs | 8 |
2 files changed, 95 insertions, 71 deletions
diff --git a/cras/client/cras_tests/src/arguments.rs b/cras/client/cras_tests/src/arguments.rs index 55d637ba..0d65b6a4 100644 --- a/cras/client/cras_tests/src/arguments.rs +++ b/cras/client/cras_tests/src/arguments.rs @@ -36,17 +36,38 @@ impl fmt::Display for Error { type Result<T> = std::result::Result<T, Error>; +/// The different types of commands that can be given to cras_tests. +/// Any options for those commands are passed as parameters to the enum values. #[derive(Debug, PartialEq)] pub enum Command { - Capture, - Playback, + Capture(AudioOptions), + Playback(AudioOptions), } -impl fmt::Display for Command { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Command::Capture => write!(f, "capture"), - Command::Playback => write!(f, "playback"), +impl Command { + pub fn parse<T: AsRef<str>>(args: &[T]) -> Result<Option<Self>> { + let program_name = args.get(0).map(|s| s.as_ref()).unwrap_or("cras_tests"); + let remaining_args = args.get(2..).unwrap_or(&[]); + match args.get(1).map(|s| s.as_ref()) { + None => { + show_usage(program_name); + Err(Error::MissingCommand) + } + Some("help") => { + show_usage(program_name); + Ok(None) + } + Some("capture") => Ok( + AudioOptions::parse(program_name, "capture", remaining_args)?.map(Command::Capture), + ), + Some("playback") => Ok( + AudioOptions::parse(program_name, "playback", remaining_args)? + .map(Command::Playback), + ), + Some(s) => { + show_usage(program_name); + Err(Error::UnknownCommand(s.to_string())) + } } } } @@ -59,13 +80,18 @@ fn show_usage(program_name: &str) { eprintln!("\nhelp - Print help message"); } -fn show_command_usage(program_name: &str, command: &Command, opts: &Options) { +fn show_command_usage(program_name: &str, command: &str, opts: &Options) { let brief = format!("Usage: {} {} [options] [filename]", program_name, command); eprint!("{}", opts.usage(&brief)); } +/// The possible command line options that can be passed to the 'playback' and +/// 'capture' commands. Optional values will be `Some(_)` only if a value was +/// explicitly provided by the user. +/// +/// This struct will be passed to `playback()` and `capture()`. +#[derive(Debug, PartialEq)] pub struct AudioOptions { - pub command: Command, pub file_name: PathBuf, pub buffer_size: Option<usize>, pub num_channels: Option<usize>, @@ -81,7 +107,11 @@ fn get_usize_param(matches: &Matches, option_name: &str) -> Result<Option<usize> } impl AudioOptions { - pub fn parse_from_args<T: AsRef<str>>(args: &[T]) -> Result<Option<Self>> { + fn parse<T: AsRef<str>>( + program_name: &str, + command_name: &str, + args: &[T], + ) -> Result<Option<Self>> { let mut opts = Options::new(); opts.optopt("b", "buffer_size", "Buffer size in frames", "SIZE") .optopt("c", "channels", "Number of channels", "NUM") @@ -94,40 +124,21 @@ impl AudioOptions { .optopt("r", "rate", "Audio frame rate (Hz)", "RATE") .optflag("h", "help", "Print help message"); - let mut args = args.into_iter().map(|s| s.as_ref()); - - let program_name = args.next().unwrap_or("cras_tests"); - let command = match args.next() { - None => { - show_usage(program_name); - return Err(Error::MissingCommand); - } - Some("help") => { - show_usage(program_name); - return Ok(None); - } - Some("capture") => Command::Capture, - Some("playback") => Command::Playback, - Some(s) => { - show_usage(program_name); - return Err(Error::UnknownCommand(s.to_string())); - } - }; - + let args = args.iter().map(|s| s.as_ref()); let matches = match opts.parse(args) { Ok(m) => m, Err(e) => { - show_command_usage(program_name, &command, &opts); + show_command_usage(program_name, command_name, &opts); return Err(Error::GetOpts(e)); } }; if matches.opt_present("h") { - show_command_usage(program_name, &command, &opts); + show_command_usage(program_name, command_name, &opts); return Ok(None); } let file_name = match matches.free.get(0) { None => { - show_command_usage(program_name, &command, &opts); + show_command_usage(program_name, command_name, &opts); return Err(Error::MissingFilename); } Some(file_name) => PathBuf::from(file_name), @@ -141,7 +152,7 @@ impl AudioOptions { Some("S24_LE") => Some(SampleFormat::S24LE), Some("S32_LE") => Some(SampleFormat::S32LE), Some(s) => { - show_command_usage(&program_name, &command, &opts); + show_command_usage(program_name, command_name, &opts); return Err(Error::InvalidArgument( "format".to_string(), s.to_string(), @@ -152,7 +163,6 @@ impl AudioOptions { }; Ok(Some(AudioOptions { - command, file_name, buffer_size, num_channels, @@ -165,29 +175,38 @@ impl AudioOptions { #[cfg(test)] mod tests { use super::*; - use std::ffi::OsString; #[test] - fn parse_from_args() { - let opts = AudioOptions::parse_from_args(&["cras_tests", "playback", "output.wav"]) + fn parse_command() { + let command = Command::parse(&["cras_tests", "playback", "output.wav"]) .unwrap() .unwrap(); - assert_eq!(opts.command, Command::Playback); - assert_eq!(opts.file_name, OsString::from("output.wav")); - assert_eq!(opts.frame_rate, None); - assert_eq!(opts.num_channels, None); - assert_eq!(opts.buffer_size, None); - - let opts = AudioOptions::parse_from_args(&["cras_tests", "capture", "input.flac"]) + assert_eq!( + command, + Command::Playback(AudioOptions { + file_name: PathBuf::from("output.wav"), + frame_rate: None, + num_channels: None, + format: None, + buffer_size: None, + }) + ); + + let command = Command::parse(&["cras_tests", "capture", "input.flac"]) .unwrap() .unwrap(); - assert_eq!(opts.command, Command::Capture); - assert_eq!(opts.file_name, OsString::from("input.flac")); - assert_eq!(opts.frame_rate, None); - assert_eq!(opts.num_channels, None); - assert_eq!(opts.buffer_size, None); - - let opts = AudioOptions::parse_from_args(&[ + assert_eq!( + command, + Command::Capture(AudioOptions { + file_name: PathBuf::from("input.flac"), + frame_rate: None, + num_channels: None, + format: None, + buffer_size: None, + }) + ); + + let command = Command::parse(&[ "cras_tests", "playback", "-r", @@ -198,21 +217,26 @@ mod tests { ]) .unwrap() .unwrap(); - assert_eq!(opts.command, Command::Playback); - assert_eq!(opts.file_name, OsString::from("output.wav")); - assert_eq!(opts.frame_rate, Some(44100)); - assert_eq!(opts.num_channels, Some(2)); - assert_eq!(opts.buffer_size, None); - - assert!(AudioOptions::parse_from_args(&["cras_tests"]).is_err()); - assert!(AudioOptions::parse_from_args(&["cras_tests", "capture"]).is_err()); - assert!(AudioOptions::parse_from_args(&["cras_tests", "playback"]).is_err()); - assert!(AudioOptions::parse_from_args(&["cras_tests", "loopback"]).is_err()); - assert!(AudioOptions::parse_from_args(&["cras_tests", "loopback", "file.ogg"]).is_err()); - assert!(AudioOptions::parse_from_args(&["cras_tests", "filename.wav"]).is_err()); - assert!(AudioOptions::parse_from_args(&["cras_tests", "filename.wav", "capture"]).is_err()); - assert!(AudioOptions::parse_from_args(&["cras_tests", "help"]).is_ok()); - assert!(AudioOptions::parse_from_args(&[ + assert_eq!( + command, + Command::Playback(AudioOptions { + file_name: PathBuf::from("output.wav"), + frame_rate: Some(44100), + num_channels: Some(2), + format: None, + buffer_size: None, + }) + ); + + assert!(Command::parse(&["cras_tests"]).is_err()); + assert!(Command::parse(&["cras_tests", "capture"]).is_err()); + assert!(Command::parse(&["cras_tests", "playback"]).is_err()); + assert!(Command::parse(&["cras_tests", "loopback"]).is_err()); + assert!(Command::parse(&["cras_tests", "loopback", "file.ogg"]).is_err()); + assert!(Command::parse(&["cras_tests", "filename.wav"]).is_err()); + assert!(Command::parse(&["cras_tests", "filename.wav", "capture"]).is_err()); + assert!(Command::parse(&["cras_tests", "help"]).is_ok()); + assert!(Command::parse(&[ "cras_tests", "-c", "2", diff --git a/cras/client/cras_tests/src/main.rs b/cras/client/cras_tests/src/main.rs index 22bb4163..4938eab9 100644 --- a/cras/client/cras_tests/src/main.rs +++ b/cras/client/cras_tests/src/main.rs @@ -175,14 +175,14 @@ fn capture(opts: AudioOptions) -> Result<()> { fn run() -> Result<()> { let args: Vec<String> = std::env::args().collect(); - let opts = match AudioOptions::parse_from_args(&args).map_err(Error::ParseArgs)? { + let command = match Command::parse(&args).map_err(Error::ParseArgs)? { None => return Ok(()), Some(v) => v, }; - match opts.command { - Command::Capture => capture(opts), - Command::Playback => playback(opts), + match command { + Command::Capture(audio_opts) => capture(audio_opts), + Command::Playback(audio_opts) => playback(audio_opts), } } |