diff --git a/src/items/date.rs b/src/items/date.rs index 835928b..34533db 100644 --- a/src/items/date.rs +++ b/src/items/date.rs @@ -138,9 +138,10 @@ pub(super) fn iso1(input: &mut &str) -> ModalResult { let (year, _, month, _, day) = (year_str, s('-'), s(dec_uint), s('-'), s(dec_uint)).parse_next(input)?; + // Map err to Backtrack instead of Cut to avoid early termination of parsing (year, month, day) .try_into() - .map_err(|e| ErrMode::Cut(ctx_err(e))) + .map_err(|e| ErrMode::Backtrack(ctx_err(e))) } /// Parse `[year][month][day]` @@ -156,7 +157,7 @@ pub(super) fn iso2(input: &mut &str) -> ModalResult { (year, month, day) .try_into() - .map_err(|e| ErrMode::Cut(ctx_err(e))) + .map_err(|e| ErrMode::Backtrack(ctx_err(e))) } /// Parse `[year]/[month]/[day]` or `[month]/[day]/[year]` or `[month]/[day]`. @@ -178,19 +179,21 @@ fn us(input: &mut &str) -> ModalResult { let day = day_from_str(s2)?; (s1, n, day) .try_into() - .map_err(|e| ErrMode::Cut(ctx_err(e))) + .map_err(|e| ErrMode::Backtrack(ctx_err(e))) } Some(s2) => { // [month]/[day]/[year] let month = month_from_str(s1)?; (s2, month, n) .try_into() - .map_err(|e| ErrMode::Cut(ctx_err(e))) + .map_err(|e| ErrMode::Backtrack(ctx_err(e))) } None => { // [month]/[day] let month = month_from_str(s1)?; - (month, n).try_into().map_err(|e| ErrMode::Cut(ctx_err(e))) + (month, n) + .try_into() + .map_err(|e| ErrMode::Backtrack(ctx_err(e))) } } } @@ -213,10 +216,10 @@ fn literal1(input: &mut &str) -> ModalResult { match year { Some(year) => (year, month, day) .try_into() - .map_err(|e| ErrMode::Cut(ctx_err(e))), + .map_err(|e| ErrMode::Backtrack(ctx_err(e))), None => (month, day) .try_into() - .map_err(|e| ErrMode::Cut(ctx_err(e))), + .map_err(|e| ErrMode::Backtrack(ctx_err(e))), } } @@ -242,10 +245,10 @@ fn literal2(input: &mut &str) -> ModalResult { match year { Some(year) => (year, month, day) .try_into() - .map_err(|e| ErrMode::Cut(ctx_err(e))), + .map_err(|e| ErrMode::Backtrack(ctx_err(e))), None => (month, day) .try_into() - .map_err(|e| ErrMode::Cut(ctx_err(e))), + .map_err(|e| ErrMode::Backtrack(ctx_err(e))), } } @@ -274,12 +277,12 @@ fn literal_month(input: &mut &str) -> ModalResult { fn month_from_str(s: &str) -> ModalResult { s.parse::() - .map_err(|_| ErrMode::Cut(ctx_err("month must be a valid u8 number"))) + .map_err(|_| ErrMode::Backtrack(ctx_err("month must be a valid u8 number"))) } fn day_from_str(s: &str) -> ModalResult { s.parse::() - .map_err(|_| ErrMode::Cut(ctx_err("day must be a valid u8 number"))) + .map_err(|_| ErrMode::Backtrack(ctx_err("day must be a valid u8 number"))) } #[cfg(test)] diff --git a/tests/time.rs b/tests/time.rs index 36bd956..b271c72 100644 --- a/tests/time.rs +++ b/tests/time.rs @@ -128,3 +128,37 @@ fn test_time_invalid(#[case] input: &str) { "Input string '{input}' did not produce an error when parsing" ); } + +#[rstest] +#[case::decimal_1_whole("1.123456789 seconds ago")] +#[case::decimal_2_whole("12.123456789 seconds ago")] +#[case::decimal_3_whole("123.123456789 seconds ago")] +#[case::decimal_4_whole("1234.123456789 seconds ago")] +#[case::decimal_5_whole("12345.123456789 seconds ago")] +#[case::decimal_6_whole("123456.123456789 seconds ago")] +#[case::decimal_7_whole("1234567.123456789 seconds ago")] +#[case::decimal_8_whole("12345678.123456789 seconds ago")] +#[case::decimal_9_whole("123456789.123456789 seconds ago")] +#[case::decimal_10_whole("1234567891.123456789 seconds ago")] +#[case::decimal_11_whole("12345678912.123456789 seconds ago")] +#[case::decimal_12_whole("123456789123.123456789 seconds ago")] +fn test_time_seconds_ago(#[case] input: &str) { + let result = parse_datetime::parse_datetime(input); + assert!( + result.is_ok(), + "Input string '{input}', produced {result:?}, instead of Ok(Zoned)" + ); +} + +#[rstest] +#[case::decimal_13_whole("1234567891234.123456789 seconds ago")] +#[case::decimal_14_whole("12345678912345.123456789 seconds ago")] +#[case::decimal_15_whole("123456789123456.123456789 seconds ago")] +fn test_time_seconds_ago_invalid(#[case] input: &str) { + let result = parse_datetime::parse_datetime(input); + assert_eq!( + result, + Err(parse_datetime::ParseDateTimeError::InvalidInput), + "Input string '{input}' did not produce an error when parsing" + ); +}