relative: Support parsing floating relative values with spaces

In case a string such as "now + 1.5 seconds" was parsed we were failing.

This happened because after processing now, the parser was getting
to the point in which the string contained "+ 1.5", and once the sign
was processed, the remaining " 1.5" string conained a space that was
causing sec_and_nsec to fail.

Instead of failing at this point, just strip the spaces after the sign has
been processed.

Note in fact that "0+0.0 seconds" was working fine

Closes: https://github.com/uutils/coreutils/issues/8618
This commit is contained in:
Marco Trevisan (Treviño)
2025-11-21 06:15:08 +01:00
parent 9f6605f20d
commit 1e4fc30f7b
2 changed files with 40 additions and 2 deletions
+4 -2
View File
@@ -83,7 +83,7 @@ pub(super) fn parse(input: &mut &str) -> ModalResult<Relative> {
fn seconds(input: &mut &str) -> ModalResult<Relative> {
(
opt(alt((s('+').value(1), s('-').value(-1)))),
sec_and_nsec,
s(sec_and_nsec),
s(alpha1).verify(|s: &str| matches!(s, "seconds" | "second" | "sec" | "secs")),
ago,
)
@@ -138,11 +138,13 @@ mod tests {
("secs", Relative::Seconds(1, 0)),
("second ago", Relative::Seconds(-1, 0)),
("3 seconds", Relative::Seconds(3, 0)),
("+ 3 seconds", Relative::Seconds(3, 0)),
("3.5 seconds", Relative::Seconds(3, 500_000_000)),
("-3.5 seconds", Relative::Seconds(-4, 500_000_000)),
("+3.5 seconds", Relative::Seconds(3, 500_000_000)),
("+ 3.5 seconds", Relative::Seconds(3, 500_000_000)),
("3.5 seconds ago", Relative::Seconds(-4, 500_000_000)),
("-3.5 seconds ago", Relative::Seconds(3, 500_000_000)),
("- 3.5 seconds ago", Relative::Seconds(3, 500_000_000)),
// Minutes
("minute", Relative::Minutes(1)),
("minutes", Relative::Minutes(1)),
+36
View File
@@ -307,6 +307,42 @@ mod tests {
assert!(parse_datetime(relative_time).is_ok());
}
}
#[test]
fn integer_seconds_offset() {
let dt = "0 + 0 seconds";
assert!(parse_datetime(dt).is_ok());
}
#[test]
fn integer_seconds_offset_spaceless() {
let dt = "0+0 seconds";
assert!(parse_datetime(dt).is_ok());
}
#[test]
fn floating_seconds_offset() {
let dt = "0 + 0.0 seconds";
assert!(parse_datetime(dt).is_ok());
}
#[test]
fn floating_seconds_offset_spaceless() {
let dt = "0+0.0 seconds";
assert!(parse_datetime(dt).is_ok());
}
#[test]
fn floating_seconds_offset_from_now() {
let dt = "now + 1.5 seconds";
assert!(parse_datetime(dt).is_ok());
}
#[test]
fn floating_seconds_offset_from_tomorrow_spaceless() {
let dt = "tomorrow+1.5 seconds";
assert!(parse_datetime(dt).is_ok());
}
}
#[cfg(test)]