diff --git a/src/config/cli.rs b/src/config/cli.rs index 52fbfa1..dc72f3a 100644 --- a/src/config/cli.rs +++ b/src/config/cli.rs @@ -81,7 +81,7 @@ pub fn build_cli() -> Command { 2018-03-04|2018-03-04 12:34:56|2018-03-04T12:34: Absolute ISO date\n \ 123456789: Absolute unix timestamp\n \ 1 year, 2 months|10d: Relative date\n \ - 1c|2 commands Emerge command"; + 1c|2 commands|c Nth emerge command"; let from = Arg::new("from").short('f') .long("from") .value_name("date") @@ -95,7 +95,7 @@ pub fn build_cli() -> Command { 2018-03-04|2018-03-04 12:34:56|2018-03-04T12:34: Absolute ISO date\n \ 123456789: Absolute unix timestamp\n \ 1 year, 2 months|10d: Relative date\n \ - 1c|2 commands Emerge command"; + 1c|2 commands|c Nth-last emerge command"; let to = Arg::new("to").short('t') .long("to") .value_name("date") diff --git a/src/datetime.rs b/src/datetime.rs index 214898e..77b17e7 100644 --- a/src/datetime.rs +++ b/src/datetime.rs @@ -111,15 +111,14 @@ impl ArgParse for TimeBound { } } -/// Parse a command index +/// Parse a command index (parse as 1-based, return as 0-based) fn parse_command_num(s: &str) -> Result { use atoi::FromRadix10; - match usize::from_radix_10(s.as_bytes()) { - (num, pos) if pos != 0 => match s[pos..].trim() { - "c" | "command" | "commands" => Ok(num), - _ => bail!("bad span {:?}", &s[pos..]), - }, - _ => bail!("not a number"), + let (num, pos) = usize::from_radix_10(s.as_bytes()); + match s[pos..].trim() { + "c" | "command" | "commands" if num > 0 => Ok(num - 1), + "c" | "command" if pos == 0 => Ok(0), + _ => bail!("bad span {:?}", &s[pos..]), } } @@ -371,6 +370,19 @@ mod test { assert!(parse_date("a while ago", tz_utc).is_err()); } + #[test] + fn command_num() { + assert_eq!(parse_command_num("1c").unwrap(), 0); + assert_eq!(parse_command_num("5c").unwrap(), 4); + assert_eq!(parse_command_num("c").unwrap(), 0); + assert_eq!(parse_command_num("1 commands ").unwrap(), 0); + assert!(parse_command_num("").is_err()); + assert!(parse_command_num("0c").is_err()); + assert!(parse_command_num("0").is_err()); + assert!(parse_command_num("1cool").is_err()); + assert!(parse_command_num("-1c").is_err()); + } + #[test] fn timespan_next_() { for t in [// input year month week day