Skip to content

Commit a6429f0

Browse files
committed
upgrade winnow to 0.7.10
1 parent 852e49e commit a6429f0

File tree

9 files changed

+114
-128
lines changed

9 files changed

+114
-128
lines changed

Cargo.lock

+2-12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,5 @@ readme = "README.md"
1010
[dependencies]
1111
regex = "1.10.4"
1212
chrono = { version="0.4.38", default-features=false, features=["std", "alloc", "clock"] }
13-
nom = "8.0.0"
14-
winnow = "0.5.34"
13+
winnow = "0.7.10"
1514
num-traits = "0.2.19"

src/items/combined.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
//! > seconds are allowed, with either comma or period preceding the fraction.
1414
//! > ISO 8601 fractional minutes and hours are not supported. Typically, hosts
1515
//! > support nanosecond timestamp resolution; excess precision is silently discarded.
16-
use winnow::{combinator::alt, seq, trace::trace, PResult, Parser};
16+
use winnow::{
17+
combinator::{alt, trace},
18+
seq, ModalResult, Parser,
19+
};
1720

1821
use crate::items::space;
1922

@@ -29,7 +32,7 @@ pub struct DateTime {
2932
pub(crate) time: Time,
3033
}
3134

32-
pub fn parse(input: &mut &str) -> PResult<DateTime> {
35+
pub fn parse(input: &mut &str) -> ModalResult<DateTime> {
3336
seq!(DateTime {
3437
date: trace("date iso", alt((date::iso1, date::iso2))),
3538
// Note: the `T` is lowercased by the main parse function

src/items/date.rs

+14-15
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,15 @@
2727
//! > ‘September’.
2828
2929
use winnow::{
30-
ascii::{alpha1, dec_uint},
31-
combinator::{alt, opt, preceded},
30+
ascii::alpha1,
31+
combinator::{alt, opt, preceded, trace},
3232
seq,
3333
stream::AsChar,
3434
token::{take, take_while},
35-
trace::trace,
36-
PResult, Parser,
35+
ModalResult, Parser,
3736
};
3837

39-
use super::s;
38+
use super::{dec_uint, s};
4039
use crate::ParseDateTimeError;
4140

4241
#[derive(PartialEq, Eq, Clone, Debug, Default)]
@@ -46,14 +45,14 @@ pub struct Date {
4645
pub year: Option<u32>,
4746
}
4847

49-
pub fn parse(input: &mut &str) -> PResult<Date> {
48+
pub fn parse(input: &mut &str) -> ModalResult<Date> {
5049
alt((iso1, iso2, us, literal1, literal2)).parse_next(input)
5150
}
5251

5352
/// Parse `YYYY-MM-DD` or `YY-MM-DD`
5453
///
5554
/// This is also used by [`combined`](super::combined).
56-
pub fn iso1(input: &mut &str) -> PResult<Date> {
55+
pub fn iso1(input: &mut &str) -> ModalResult<Date> {
5756
seq!(Date {
5857
year: year.map(Some),
5958
_: s('-'),
@@ -67,7 +66,7 @@ pub fn iso1(input: &mut &str) -> PResult<Date> {
6766
/// Parse `YYYYMMDD`
6867
///
6968
/// This is also used by [`combined`](super::combined).
70-
pub fn iso2(input: &mut &str) -> PResult<Date> {
69+
pub fn iso2(input: &mut &str) -> ModalResult<Date> {
7170
s((
7271
take(4usize).try_map(|s: &str| s.parse::<u32>()),
7372
take(2usize).try_map(|s: &str| s.parse::<u32>()),
@@ -82,7 +81,7 @@ pub fn iso2(input: &mut &str) -> PResult<Date> {
8281
}
8382

8483
/// Parse `MM/DD/YYYY`, `MM/DD/YY` or `MM/DD`
85-
fn us(input: &mut &str) -> PResult<Date> {
84+
fn us(input: &mut &str) -> ModalResult<Date> {
8685
seq!(Date {
8786
month: month,
8887
_: s('/'),
@@ -93,7 +92,7 @@ fn us(input: &mut &str) -> PResult<Date> {
9392
}
9493

9594
/// Parse `14 November 2022`, `14 Nov 2022`, "14nov2022", "14-nov-2022", "14-nov2022", "14nov-2022"
96-
fn literal1(input: &mut &str) -> PResult<Date> {
95+
fn literal1(input: &mut &str) -> ModalResult<Date> {
9796
seq!(Date {
9897
day: day,
9998
_: opt(s('-')),
@@ -104,7 +103,7 @@ fn literal1(input: &mut &str) -> PResult<Date> {
104103
}
105104

106105
/// Parse `November 14, 2022` and `Nov 14, 2022`
107-
fn literal2(input: &mut &str) -> PResult<Date> {
106+
fn literal2(input: &mut &str) -> ModalResult<Date> {
108107
seq!(Date {
109108
month: literal_month,
110109
day: day,
@@ -115,7 +114,7 @@ fn literal2(input: &mut &str) -> PResult<Date> {
115114
.parse_next(input)
116115
}
117116

118-
pub fn year(input: &mut &str) -> PResult<u32> {
117+
pub fn year(input: &mut &str) -> ModalResult<u32> {
119118
// 2147485547 is the maximum value accepted
120119
// by GNU, but chrono only behaves like GNU
121120
// for years in the range: [0, 9999], so we
@@ -140,7 +139,7 @@ pub fn year(input: &mut &str) -> PResult<u32> {
140139
.parse_next(input)
141140
}
142141

143-
fn month(input: &mut &str) -> PResult<u32> {
142+
fn month(input: &mut &str) -> ModalResult<u32> {
144143
s(dec_uint)
145144
.try_map(|x| {
146145
(1..=12)
@@ -151,7 +150,7 @@ fn month(input: &mut &str) -> PResult<u32> {
151150
.parse_next(input)
152151
}
153152

154-
fn day(input: &mut &str) -> PResult<u32> {
153+
fn day(input: &mut &str) -> ModalResult<u32> {
155154
s(dec_uint)
156155
.try_map(|x| {
157156
(1..=31)
@@ -163,7 +162,7 @@ fn day(input: &mut &str) -> PResult<u32> {
163162
}
164163

165164
/// Parse the name of a month (case-insensitive)
166-
fn literal_month(input: &mut &str) -> PResult<u32> {
165+
fn literal_month(input: &mut &str) -> ModalResult<u32> {
167166
s(alpha1)
168167
.verify_map(|s: &str| {
169168
Some(match s {

src/items/mod.rs

+57-47
Original file line numberDiff line numberDiff line change
@@ -34,34 +34,32 @@ mod relative;
3434
mod time;
3535
mod weekday;
3636
mod epoch {
37-
use winnow::{ascii::dec_int, combinator::preceded, PResult, Parser};
37+
use winnow::{combinator::preceded, ModalResult, Parser};
3838

39-
use super::s;
40-
pub fn parse(input: &mut &str) -> PResult<i32> {
39+
use super::{dec_int, s};
40+
pub fn parse(input: &mut &str) -> ModalResult<i32> {
4141
s(preceded("@", dec_int)).parse_next(input)
4242
}
4343
}
4444
mod timezone {
4545
use super::time;
46-
use winnow::PResult;
46+
use winnow::ModalResult;
4747

48-
pub(crate) fn parse(input: &mut &str) -> PResult<time::Offset> {
48+
pub(crate) fn parse(input: &mut &str) -> ModalResult<time::Offset> {
4949
time::timezone(input)
5050
}
5151
}
5252

5353
use chrono::NaiveDate;
5454
use chrono::{DateTime, Datelike, FixedOffset, TimeZone, Timelike};
5555

56-
use winnow::error::{AddContext, ParserError, StrContext};
57-
use winnow::error::{ContextError, ErrMode};
58-
use winnow::trace::trace;
5956
use winnow::{
60-
ascii::multispace0,
61-
combinator::{alt, delimited, not, peek, preceded, repeat, separated},
57+
ascii::{digit1, multispace0},
58+
combinator::{alt, delimited, not, opt, peek, preceded, repeat, separated, trace},
59+
error::{ContextError, ErrMode, ParserError},
6260
stream::AsChar,
63-
token::{none_of, take_while},
64-
PResult, Parser,
61+
token::{none_of, one_of, take_while},
62+
ModalResult, Parser,
6563
};
6664

6765
use crate::ParseDateTimeError;
@@ -93,7 +91,7 @@ where
9391
/// Parse the space in-between tokens
9492
///
9593
/// You probably want to use the [`s`] combinator instead.
96-
fn space<'a, E>(input: &mut &'a str) -> PResult<(), E>
94+
fn space<'a, E>(input: &mut &'a str) -> winnow::Result<(), E>
9795
where
9896
E: ParserError<&'a str>,
9997
{
@@ -110,7 +108,7 @@ where
110108
/// The last comment should be ignored.
111109
///
112110
/// The plus is undocumented, but it seems to be ignored.
113-
fn ignored_hyphen_or_plus<'a, E>(input: &mut &'a str) -> PResult<(), E>
111+
fn ignored_hyphen_or_plus<'a, E>(input: &mut &'a str) -> winnow::Result<(), E>
114112
where
115113
E: ParserError<&'a str>,
116114
{
@@ -127,7 +125,7 @@ where
127125
///
128126
/// A comment is given between parentheses, which must be balanced. Any other
129127
/// tokens can be within the comment.
130-
fn comment<'a, E>(input: &mut &'a str) -> PResult<(), E>
128+
fn comment<'a, E>(input: &mut &'a str) -> winnow::Result<(), E>
131129
where
132130
E: ParserError<&'a str>,
133131
{
@@ -139,8 +137,45 @@ where
139137
.parse_next(input)
140138
}
141139

140+
/// Parse a signed decimal integer.
141+
///
142+
/// Rationale for not using `winnow::ascii::dec_int`: When upgrading winnow from
143+
/// 0.5 to 0.7, we discovered that `winnow::ascii::dec_int` now accepts only the
144+
/// following two forms:
145+
///
146+
/// - 0
147+
/// - [+-][1-9][0-9]*
148+
///
149+
/// Inputs like [+-]0[0-9]* (e.g., `+012`) are therefore rejected. We provide a
150+
/// custom implementation to support such zero-prefixed integers.
151+
fn dec_int<'a, E>(input: &mut &'a str) -> winnow::Result<i32, E>
152+
where
153+
E: ParserError<&'a str>,
154+
{
155+
(opt(one_of(['+', '-'])), digit1)
156+
.void()
157+
.take()
158+
.verify_map(|s: &str| s.parse().ok())
159+
.parse_next(input)
160+
}
161+
162+
/// Parse an unsigned decimal integer.
163+
///
164+
/// See the rationale for `dec_int` for why we don't use
165+
/// `winnow::ascii::dec_uint`.
166+
fn dec_uint<'a, E>(input: &mut &'a str) -> winnow::Result<u32, E>
167+
where
168+
E: ParserError<&'a str>,
169+
{
170+
digit1
171+
.void()
172+
.take()
173+
.verify_map(|s: &str| s.parse().ok())
174+
.parse_next(input)
175+
}
176+
142177
// Parse an item
143-
pub fn parse_one(input: &mut &str) -> PResult<Item> {
178+
pub fn parse_one(input: &mut &str) -> ModalResult<Item> {
144179
trace(
145180
"parse_one",
146181
alt((
@@ -157,7 +192,7 @@ pub fn parse_one(input: &mut &str) -> PResult<Item> {
157192
.parse_next(input)
158193
}
159194

160-
pub fn parse(input: &mut &str) -> PResult<Vec<Item>> {
195+
pub fn parse(input: &mut &str) -> ModalResult<Vec<Item>> {
161196
let mut items = Vec::new();
162197
let mut date_seen = false;
163198
let mut time_seen = false;
@@ -170,12 +205,7 @@ pub fn parse(input: &mut &str) -> PResult<Vec<Item>> {
170205
match item {
171206
Item::DateTime(ref dt) => {
172207
if date_seen || time_seen {
173-
return Err(ErrMode::Backtrack(ContextError::new().add_context(
174-
&input,
175-
StrContext::Expected(winnow::error::StrContextValue::Description(
176-
"date or time cannot appear more than once",
177-
)),
178-
)));
208+
return Err(ErrMode::Backtrack(ContextError::new()));
179209
}
180210

181211
date_seen = true;
@@ -186,12 +216,7 @@ pub fn parse(input: &mut &str) -> PResult<Vec<Item>> {
186216
}
187217
Item::Date(ref d) => {
188218
if date_seen {
189-
return Err(ErrMode::Backtrack(ContextError::new().add_context(
190-
&input,
191-
StrContext::Expected(winnow::error::StrContextValue::Description(
192-
"date cannot appear more than once",
193-
)),
194-
)));
219+
return Err(ErrMode::Backtrack(ContextError::new()));
195220
}
196221

197222
date_seen = true;
@@ -201,34 +226,19 @@ pub fn parse(input: &mut &str) -> PResult<Vec<Item>> {
201226
}
202227
Item::Time(_) => {
203228
if time_seen {
204-
return Err(ErrMode::Backtrack(ContextError::new().add_context(
205-
&input,
206-
StrContext::Expected(winnow::error::StrContextValue::Description(
207-
"time cannot appear more than once",
208-
)),
209-
)));
229+
return Err(ErrMode::Backtrack(ContextError::new()));
210230
}
211231
time_seen = true;
212232
}
213233
Item::Year(_) => {
214234
if year_seen {
215-
return Err(ErrMode::Backtrack(ContextError::new().add_context(
216-
&input,
217-
StrContext::Expected(winnow::error::StrContextValue::Description(
218-
"year cannot appear more than once",
219-
)),
220-
)));
235+
return Err(ErrMode::Backtrack(ContextError::new()));
221236
}
222237
year_seen = true;
223238
}
224239
Item::TimeZone(_) => {
225240
if tz_seen {
226-
return Err(ErrMode::Backtrack(ContextError::new().add_context(
227-
&input,
228-
StrContext::Expected(winnow::error::StrContextValue::Description(
229-
"timezone cannot appear more than once",
230-
)),
231-
)));
241+
return Err(ErrMode::Backtrack(ContextError::new()));
232242
}
233243
tz_seen = true;
234244
}

src/items/ordinal.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ use super::s;
55
use winnow::{
66
ascii::{alpha1, dec_uint},
77
combinator::{alt, opt},
8-
PResult, Parser,
8+
ModalResult, Parser,
99
};
1010

11-
pub fn ordinal(input: &mut &str) -> PResult<i32> {
11+
pub fn ordinal(input: &mut &str) -> ModalResult<i32> {
1212
alt((text_ordinal, number_ordinal)).parse_next(input)
1313
}
1414

15-
fn number_ordinal(input: &mut &str) -> PResult<i32> {
15+
fn number_ordinal(input: &mut &str) -> ModalResult<i32> {
1616
let sign = opt(alt(('+'.value(1), '-'.value(-1)))).map(|s| s.unwrap_or(1));
1717
(s(sign), s(dec_uint))
1818
.verify_map(|(s, u): (i32, u32)| {
@@ -22,7 +22,7 @@ fn number_ordinal(input: &mut &str) -> PResult<i32> {
2222
.parse_next(input)
2323
}
2424

25-
fn text_ordinal(input: &mut &str) -> PResult<i32> {
25+
fn text_ordinal(input: &mut &str) -> ModalResult<i32> {
2626
s(alpha1)
2727
.verify_map(|s: &str| {
2828
Some(match s {

0 commit comments

Comments
 (0)