|
21 | 21 | //! >
|
22 | 22 | //! > A comma following a day of the week item is ignored.
|
23 | 23 |
|
24 |
| -use winnow::{ascii::alpha1, combinator::opt, seq, ModalResult, Parser}; |
| 24 | +use winnow::{ |
| 25 | + ascii::alpha1, |
| 26 | + combinator::{opt, terminated}, |
| 27 | + seq, ModalResult, Parser, |
| 28 | +}; |
25 | 29 |
|
26 | 30 | use super::{ordinal::ordinal, primitive::s};
|
27 | 31 |
|
@@ -55,10 +59,26 @@ impl From<Day> for chrono::Weekday {
|
55 | 59 | }
|
56 | 60 | }
|
57 | 61 | }
|
| 62 | + |
| 63 | +/// Parse a weekday item. |
| 64 | +/// |
| 65 | +/// Grammar: |
| 66 | +/// |
| 67 | +/// ```ebnf |
| 68 | +/// weekday = [ ordinal ] day [ "," ] ; |
| 69 | +/// |
| 70 | +/// day = "monday" | "mon" | "mon." |
| 71 | +/// | "tuesday" | "tue" | "tue." | "tues" |
| 72 | +/// | "wednesday" | "wed" | "wed." | "wednes" |
| 73 | +/// | "thursday" | "thu" | "thu." | "thur" | "thurs" |
| 74 | +/// | "friday" | "fri" | "fri." |
| 75 | +/// | "saturday" | "sat" | "sat." |
| 76 | +/// | "sunday" | "sun" | "sun." ; |
| 77 | +/// ``` |
58 | 78 | pub fn parse(input: &mut &str) -> ModalResult<Weekday> {
|
59 | 79 | seq!(Weekday {
|
60 | 80 | offset: opt(ordinal).map(|o| o.unwrap_or_default()),
|
61 |
| - day: day, |
| 81 | + day: terminated(day, opt(s(","))), |
62 | 82 | })
|
63 | 83 | .parse_next(input)
|
64 | 84 | }
|
@@ -134,4 +154,17 @@ mod tests {
|
134 | 154 | );
|
135 | 155 | }
|
136 | 156 | }
|
| 157 | + |
| 158 | + #[test] |
| 159 | + fn optional_comma() { |
| 160 | + for mut s in ["monday,", "mon,", "mon.,", "mon. ,"] { |
| 161 | + assert_eq!( |
| 162 | + parse(&mut s).unwrap(), |
| 163 | + Weekday { |
| 164 | + offset: 0, |
| 165 | + day: Day::Monday, |
| 166 | + } |
| 167 | + ); |
| 168 | + } |
| 169 | + } |
137 | 170 | }
|
0 commit comments