Skip to content

Commit 77156f4

Browse files
Merge pull request #137 from yuankunzhang/replace-the-regex-parser
Replace the regex parser with winnow-based parse
2 parents b481a2b + bc6b70b commit 77156f4

File tree

11 files changed

+2242
-313
lines changed

11 files changed

+2242
-313
lines changed

Cargo.lock

Lines changed: 31 additions & 20 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ readme = "README.md"
1111
regex = "1.10.4"
1212
chrono = { version="0.4.38", default-features=false, features=["std", "alloc", "clock"] }
1313
nom = "8.0.0"
14+
winnow = "0.5.34"
15+
num-traits = "0.2.19"

fuzz/Cargo.lock

Lines changed: 13 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/items/combined.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// For the full copyright and license information, please view the LICENSE
2+
// file that was distributed with this source code.
3+
4+
//! Parse an ISO 8601 date and time item
5+
//!
6+
//! The GNU docs state:
7+
//!
8+
//! > The ISO 8601 date and time of day extended format consists of an ISO 8601
9+
//! > date, a ‘T’ character separator, and an ISO 8601 time of day. This format
10+
//! > is also recognized if the ‘T’ is replaced by a space.
11+
//! >
12+
//! > In this format, the time of day should use 24-hour notation. Fractional
13+
//! > seconds are allowed, with either comma or period preceding the fraction.
14+
//! > ISO 8601 fractional minutes and hours are not supported. Typically, hosts
15+
//! > support nanosecond timestamp resolution; excess precision is silently discarded.
16+
use winnow::{combinator::alt, seq, trace::trace, PResult, Parser};
17+
18+
use crate::items::space;
19+
20+
use super::{
21+
date::{self, Date},
22+
s,
23+
time::{self, Time},
24+
};
25+
26+
#[derive(PartialEq, Debug, Clone, Default)]
27+
pub struct DateTime {
28+
pub(crate) date: Date,
29+
pub(crate) time: Time,
30+
}
31+
32+
pub fn parse(input: &mut &str) -> PResult<DateTime> {
33+
seq!(DateTime {
34+
date: trace("date iso", alt((date::iso1, date::iso2))),
35+
// Note: the `T` is lowercased by the main parse function
36+
_: alt((s('t').void(), (' ', space).void())),
37+
time: trace("time iso", time::iso),
38+
})
39+
.parse_next(input)
40+
}
41+
42+
#[cfg(test)]
43+
mod tests {
44+
use super::{parse, DateTime};
45+
use crate::items::{date::Date, time::Time};
46+
47+
#[test]
48+
fn some_date() {
49+
let reference = Some(DateTime {
50+
date: Date {
51+
day: 10,
52+
month: 10,
53+
year: Some(2022),
54+
},
55+
time: Time {
56+
hour: 10,
57+
minute: 10,
58+
second: 55.0,
59+
offset: None,
60+
},
61+
});
62+
63+
for mut s in [
64+
"2022-10-10t10:10:55",
65+
"2022-10-10 10:10:55",
66+
"2022-10-10 t 10:10:55",
67+
"2022-10-10 10:10:55",
68+
"2022-10-10 (A comment!) t 10:10:55",
69+
"2022-10-10 (A comment!) 10:10:55",
70+
] {
71+
let old_s = s.to_owned();
72+
assert_eq!(parse(&mut s).ok(), reference, "Failed string: {old_s}")
73+
}
74+
}
75+
}

0 commit comments

Comments
 (0)