Skip to content

Commit cbfc1cf

Browse files
committed
Code review changes
1 parent d3383c7 commit cbfc1cf

File tree

1 file changed

+30
-17
lines changed

1 file changed

+30
-17
lines changed

src/parse_timestamp.rs

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,40 @@
1-
use nom::combinator::map;
1+
use nom::branch::alt;
2+
use nom::character::complete::{char, digit1};
3+
use nom::combinator::all_consuming;
4+
use nom::multi::fold_many0;
5+
use nom::sequence::preceded;
6+
use nom::sequence::tuple;
27
use nom::{self, IResult};
38

49
pub(crate) fn parse_timestamp(s: &str) -> Option<i64> {
510
let s = s.trim().to_lowercase();
611
let s = s.as_str();
712

8-
let res: IResult<&str, (&str, char, &str)> =
9-
nom::combinator::all_consuming(nom::sequence::tuple((
10-
nom::bytes::complete::tag("@"),
11-
map(
12-
nom::bytes::complete::take_while(|c: char| c == '+' || c == '-'),
13-
|st: &str| st.chars().last().unwrap_or('+'),
13+
let res: IResult<&str, (char, &str)> = all_consuming(preceded(
14+
char('@'),
15+
tuple((
16+
// Note: gnu date allows multiple + and - and only considers the last one
17+
fold_many0(
18+
// parse either + or -
19+
alt((char('+'), char('-'))),
20+
// start with a +
21+
|| '+',
22+
// whatever we get (+ or -), update the accumulator to that value
23+
|_, c| c,
1424
),
15-
nom::character::complete::digit1,
16-
)))(s);
25+
digit1,
26+
)),
27+
))(s);
1728

18-
if let Ok((_, (_, sign, number_str))) = res {
19-
let number = format!("{}{}", sign, number_str).parse();
29+
let (_, (sign, number_str)) = res.ok()?;
2030

21-
return match number {
22-
Err(_) => None,
23-
Ok(val) => Some(val),
24-
};
31+
let mut number = number_str.parse::<i64>().ok()?;
32+
33+
if sign == '-' {
34+
number *= -1;
2535
}
2636

27-
None
37+
Some(number)
2838
}
2939

3040
#[cfg(test)]
@@ -41,7 +51,9 @@ mod tests {
4151
assert_eq!(parse_timestamp("@+4"), Some(4));
4252
assert_eq!(parse_timestamp("@0"), Some(0));
4353

44-
// gnu date accepts this
54+
// gnu date acceppts numbers signs and uses the last sign
55+
assert_eq!(parse_timestamp("@---+12"), Some(12));
56+
assert_eq!(parse_timestamp("@+++-12"), Some(-12));
4557
assert_eq!(parse_timestamp("@+----+12"), Some(12));
4658
assert_eq!(parse_timestamp("@++++-123"), Some(-123));
4759
}
@@ -50,5 +62,6 @@ mod tests {
5062
fn test_invalid_timestamp() {
5163
assert_eq!(parse_timestamp("@"), None);
5264
assert_eq!(parse_timestamp("@+--+"), None);
65+
assert_eq!(parse_timestamp("@+1ab2"), None);
5366
}
5467
}

0 commit comments

Comments
 (0)