diff options
author | onielfa <onielfadev@gmail.com> | 2020-07-24 00:55:04 +0200 |
---|---|---|
committer | onielfa <onielfadev@gmail.com> | 2020-07-24 00:55:04 +0200 |
commit | 242d58264df4842464e12c70297608bc0833d632 (patch) | |
tree | b72df81bbaaa1d5a8acd1a869be41e65796e2b12 | |
parent | 5c910bc6cf193725575ef6146dcc8620e7a4a800 (diff) |
Allow names longer that one word
-rw-r--r-- | src/command.rs | 98 |
1 files changed, 80 insertions, 18 deletions
diff --git a/src/command.rs b/src/command.rs index 38d48e9..a893430 100644 --- a/src/command.rs +++ b/src/command.rs @@ -122,7 +122,6 @@ pub enum Command { #[derive(Debug)] pub enum CommandLineError { InvalidCommand(String), // command name - InvalidArg(u32), // position NotEnoughArgs(String, u32), // command name, required no. of args } @@ -132,7 +131,6 @@ impl fmt::Display for CommandLineError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { CommandLineError::InvalidCommand(s) => write!(f, "Invalid command: `{}`", s), - CommandLineError::InvalidArg(p) => write!(f, "Invalid argument at position {}", p), CommandLineError::NotEnoughArgs(s, n) => { write!(f, "Command `{}` requires atleast {} argument(s)!", s, n) } @@ -150,23 +148,9 @@ impl Command { } let first = strings.first().unwrap().to_string(); - let mut args: Vec<String> = strings.iter_mut().skip(1).map(|s| s.to_string()).collect(); + let args: Vec<String> = strings.iter_mut().skip(1).map(|s| s.to_string()).collect(); let mut _add = |auto: bool, first: String| { - if args.is_empty() { - return Err(CommandLineError::NotEnoughArgs(first, 1)); - } - let goal = args - .get(1) - .map(|x| { - x.parse::<u32>() - .map_err(|_| CommandLineError::InvalidArg(2)) - }) - .transpose()?; - return Ok(Command::Add( - args.get_mut(0).unwrap().to_string(), - goal, - auto, - )); + return parse_add(first, args.clone(), auto); }; match first.as_ref() { @@ -205,3 +189,81 @@ impl Command { } } } + +fn parse_add(verb: String, args: Vec<String>, auto: bool) -> Result<Command> { + if args.is_empty() { + return Err(CommandLineError::NotEnoughArgs(verb, 1)); + } + + let mut pos = 1; + let mut acc = "".to_owned(); + let mut new_goal: Option<u32> = None; + for s1 in args { + if pos == 1 { + acc.push_str(&s1); + } else { + if let Ok(n) = s1.parse::<u32>() { + new_goal = Some(n); + } else { + acc.push(' '); + acc.push_str(&s1); + } + } + pos = pos + 1; + } + + return Ok(Command::Add(acc, new_goal, auto)); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn parse_add_command_with_goal() { + let command: Vec<String> = "eat healthy 3" + .trim() + .split(' ') + .into_iter() + .map(|s| s.to_string()) + .collect(); + + let verb = "add".to_owned(); + let auto = false; + + let result = parse_add(verb, command, auto); + + match result.unwrap() { + Command::Add(name, goal, a) => { + assert_eq!(name, "eat healthy".to_owned()); + assert_eq!(goal.unwrap(), 3); + assert_eq!(a, auto); + } + _ => panic!(), + } + } + + #[test] + fn parse_add_command_without_goal() { + let command: Vec<String> = "eat healthy" + .trim() + .split(' ') + .into_iter() + .map(|s| s.to_string()) + .collect(); + + let verb = "add".to_owned(); + let auto = false; + + let result = parse_add(verb, command, auto); + + match result.unwrap() { + Command::Add(name, goal, a) => { + assert_eq!(name, "eat healthy".to_owned()); + assert!(goal.is_none()); + assert_eq!(a, auto); + } + _ => panic!(), + } + } +} |