diff --git a/src/input/shared.rs b/src/input/shared.rs index fe26c503d..95b9912a5 100644 --- a/src/input/shared.rs +++ b/src/input/shared.rs @@ -114,8 +114,13 @@ fn clean_int_str(mut s: &str) -> Option> { // strip leading and trailing whitespace s = s.trim(); - // strip leading unary plus - s = s.strip_prefix('+').unwrap_or(s); + // Check for and remove a leading unary plus and ensure the next character is not a unary minus. e.g.: '+-1'. + if let Some(suffix) = s.strip_prefix('+') { + if suffix.starts_with('-') { + return None; + } + s = suffix; + } // strip loading zeros s = strip_leading_zeros(s)?; @@ -149,8 +154,8 @@ fn strip_leading_zeros(s: &str) -> Option<&str> { match char_iter.next() { // if we get a leading zero we continue Some((_, '0')) => (), - // if we get another digit we return the whole string - Some((_, c)) if ('1'..='9').contains(&c) => return Some(s), + // if we get another digit or unary minus we return the whole string + Some((_, c)) if ('1'..='9').contains(&c) || c == '-' => return Some(s), // anything else is invalid, we return None _ => return None, }; @@ -158,8 +163,8 @@ fn strip_leading_zeros(s: &str) -> Option<&str> { match c { // continue on more leading zeros or if we get an underscore we continue - we're "within the number" '0' | '_' => (), - // any other digit we return the rest of the string - '1'..='9' => return Some(&s[i..]), + // any other digit or unary minus we return the rest of the string + '1'..='9' | '-' => return Some(&s[i..]), // if we get a dot we return the rest of the string but include the last zero '.' => return Some(&s[(i - 1)..]), // anything else is invalid, we return None diff --git a/tests/validators/test_int.py b/tests/validators/test_int.py index 5732fe181..f93919f17 100644 --- a/tests/validators/test_int.py +++ b/tests/validators/test_int.py @@ -29,6 +29,8 @@ ('+0_000', 0), (1, 1), (' 1 ', 1), + ('-1', -1), + ('-1.0', -1), (42, 42), ('42', 42), (42.0, 42), @@ -48,6 +50,7 @@ ('+4_2.0', 42), ('+04_2.0', 42), ('++4_2', Err('Input should be a valid integer, unable to parse string as an integer')), + ('-+1', Err('Input should be a valid integer, unable to parse string as an integer')), ('+-1', Err('Input should be a valid integer, unable to parse string as an integer')), ('4_2', 42), ('0_42', 42),