From a68f15e034c8711c7ae2c4bb1db269b4b4e134ab Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Mon, 24 Apr 2023 00:07:34 +0200 Subject: [PATCH] from_str('Thu Jan 01 12:34:00 2015') should fail --- src/lib.rs | 23 +++++++++++++++++++---- tests/simple.rs | 13 ++++++++++++- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 25fcbd2..4ff1e52 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -80,15 +80,20 @@ impl From for ParseDurationError { pub fn from_str(s: &str) -> Result { let time_pattern: Regex = Regex::new( r"(?x) - (?P[-+]?\d*)\s* - (?Pyears?|months?|fortnights?|weeks?|days?|hours?|h|minutes?|mins?|m|seconds?|secs?|s|yesterday|tomorrow|now|today) - (\s*(?Pand|,)?\s*)?", + (?:(?P[-+]?\d*)\s*)? + (?Pyears?|months?|fortnights?|weeks?|days?|hours?|h|minutes?|mins?|m|seconds?|secs?|s|yesterday|tomorrow|now|today) + (\s*(?Pand|,)?\s*)? + (\s*(?Pago)?)?", )?; let mut total_duration = Duration::ZERO; let mut is_ago = s.contains(" ago"); + let mut captures_processed = 0; + let mut total_length = 0; for capture in time_pattern.captures_iter(s) { + captures_processed += 1; + let value_str = capture .name("value") .ok_or(ParseDurationError::InvalidInput)? @@ -129,9 +134,19 @@ pub fn from_str(s: &str) -> Result { Some(duration) => duration, None => return Err(ParseDurationError::InvalidInput), }; + + // Calculate the total length of the matched substring + if let Some(m) = capture.get(0) { + total_length += m.end() - m.start(); + } } - if total_duration == Duration::ZERO && !time_pattern.is_match(s) { + // Check if the entire input string has been captured + if total_length != s.len() { + return Err(ParseDurationError::InvalidInput); + } + + if captures_processed == 0 { Err(ParseDurationError::InvalidInput) } else { Ok(total_duration) diff --git a/tests/simple.rs b/tests/simple.rs index 6330560..3cf9b24 100644 --- a/tests/simple.rs +++ b/tests/simple.rs @@ -120,7 +120,18 @@ fn test_display_parse_duration_error_through_from_str() { let error = from_str(invalid_input).unwrap_err(); assert_eq!( - format!("{}", error), + format!("{error}"), + "Invalid input string: cannot be parsed as a relative time" + ); +} + +#[test] +fn test_display_should_fail() { + let invalid_input = "Thu Jan 01 12:34:00 2015"; + let error = from_str(invalid_input).unwrap_err(); + + assert_eq!( + format!("{error}"), "Invalid input string: cannot be parsed as a relative time" ); }