Skip to content

Commit 11ac79c

Browse files
authored
Merge pull request #1822 from epage/w7
Upgrade to Winnow 0.7
2 parents 914bf28 + fdc57e7 commit 11ac79c

File tree

23 files changed

+134
-124
lines changed

23 files changed

+134
-124
lines changed

Cargo.lock

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

gix-actor/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ bstr = { version = "1.3.0", default-features = false, features = [
2727
"std",
2828
"unicode",
2929
] }
30-
winnow = { version = "0.6", features = ["simd"] }
30+
winnow = { version = "0.7.0", features = ["simd"] }
3131
itoa = "1.0.1"
3232
serde = { version = "1.0.114", optional = true, default-features = false, features = [
3333
"derive",

gix-actor/src/signature/decode.rs

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ pub(crate) mod function {
33
use bstr::ByteSlice;
44
use gix_date::{time::Sign, OffsetInSeconds, SecondsSinceUnixEpoch, Time};
55
use gix_utils::btoi::to_signed;
6-
use winnow::error::{ErrMode, ErrorKind};
6+
use winnow::error::ErrMode;
77
use winnow::stream::Stream;
88
use winnow::{
99
combinator::{alt, opt, separated_pair, terminated},
@@ -18,7 +18,7 @@ pub(crate) mod function {
1818
/// Parse a signature from the bytes input `i` using `nom`.
1919
pub fn decode<'a, E: ParserError<&'a [u8]> + AddContext<&'a [u8], StrContext>>(
2020
i: &mut &'a [u8],
21-
) -> PResult<SignatureRef<'a>, E> {
21+
) -> ModalResult<SignatureRef<'a>, E> {
2222
separated_pair(
2323
identity,
2424
opt(b" "),
@@ -68,31 +68,29 @@ pub(crate) mod function {
6868
/// Parse an identity from the bytes input `i` (like `name <email>`) using `nom`.
6969
pub fn identity<'a, E: ParserError<&'a [u8]> + AddContext<&'a [u8], StrContext>>(
7070
i: &mut &'a [u8],
71-
) -> PResult<IdentityRef<'a>, E> {
71+
) -> ModalResult<IdentityRef<'a>, E> {
7272
let start = i.checkpoint();
7373
let eol_idx = i.find_byte(b'\n').unwrap_or(i.len());
74-
let right_delim_idx =
75-
i[..eol_idx]
76-
.rfind_byte(b'>')
77-
.ok_or(ErrMode::Cut(E::from_error_kind(i, ErrorKind::Eof).add_context(
78-
i,
79-
&start,
80-
StrContext::Label("Closing '>' not found"),
81-
)))?;
74+
let right_delim_idx = i[..eol_idx]
75+
.rfind_byte(b'>')
76+
.ok_or(ErrMode::Cut(E::from_input(i).add_context(
77+
i,
78+
&start,
79+
StrContext::Label("Closing '>' not found"),
80+
)))?;
8281
let i_name_and_email = &i[..right_delim_idx];
8382
let skip_from_right = i_name_and_email
8483
.iter()
8584
.rev()
8685
.take_while(|b| b.is_ascii_whitespace() || **b == b'>')
8786
.count();
88-
let left_delim_idx =
89-
i_name_and_email
90-
.find_byte(b'<')
91-
.ok_or(ErrMode::Cut(E::from_error_kind(i, ErrorKind::Eof).add_context(
92-
&i_name_and_email,
93-
&start,
94-
StrContext::Label("Opening '<' not found"),
95-
)))?;
87+
let left_delim_idx = i_name_and_email
88+
.find_byte(b'<')
89+
.ok_or(ErrMode::Cut(E::from_input(i).add_context(
90+
&i_name_and_email,
91+
&start,
92+
StrContext::Label("Opening '<' not found"),
93+
)))?;
9694
let skip_from_left = i[left_delim_idx..]
9795
.iter()
9896
.take_while(|b| b.is_ascii_whitespace() || **b == b'<')
@@ -102,7 +100,7 @@ pub(crate) mod function {
102100

103101
let email = i
104102
.get(left_delim_idx + skip_from_left..right_delim_idx - skip_from_right)
105-
.ok_or(ErrMode::Cut(E::from_error_kind(i, ErrorKind::Eof).add_context(
103+
.ok_or(ErrMode::Cut(E::from_input(i).add_context(
106104
&i_name_and_email,
107105
&start,
108106
StrContext::Label("Skipped parts run into each other"),
@@ -126,7 +124,7 @@ mod tests {
126124

127125
fn decode<'i>(
128126
i: &mut &'i [u8],
129-
) -> PResult<SignatureRef<'i>, winnow::error::TreeError<&'i [u8], winnow::error::StrContext>> {
127+
) -> ModalResult<SignatureRef<'i>, winnow::error::TreeError<&'i [u8], winnow::error::StrContext>> {
130128
signature::decode.parse_next(i)
131129
}
132130

@@ -203,7 +201,7 @@ mod tests {
203201
.map_err(to_bstr_err)
204202
.expect_err("parse fails as > is missing")
205203
.to_string(),
206-
"in end of file at 'hello < 12345 -1215'\n 0: invalid Closing '>' not found at 'hello < 12345 -1215'\n 1: expected `<name> <<email>> <timestamp> <+|-><HHMM>` at 'hello < 12345 -1215'\n"
204+
" at 'hello < 12345 -1215'\n 0: invalid Closing '>' not found at 'hello < 12345 -1215'\n 1: expected `<name> <<email>> <timestamp> <+|-><HHMM>` at 'hello < 12345 -1215'\n"
207205
);
208206
}
209207

gix-config/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ gix-sec = { version = "^0.10.11", path = "../gix-sec" }
2626
gix-ref = { version = "^0.50.0", path = "../gix-ref" }
2727
gix-glob = { version = "^0.18.0", path = "../gix-glob" }
2828

29-
winnow = { version = "0.6", features = ["simd"] }
29+
winnow = { version = "0.7.0", features = ["simd"] }
3030
memchr = "2"
3131
thiserror = "2.0.0"
3232
unicode-bom = { version = "2.0.3" }

gix-config/src/parse/nom/mod.rs

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ use std::borrow::Cow;
33
use bstr::{BStr, ByteSlice};
44
use winnow::{
55
combinator::{alt, delimited, opt, preceded, repeat},
6-
error::{ErrorKind, InputError as NomError, ParserError as _},
6+
error::{ErrMode, InputError as NomError, ParserError as _},
77
prelude::*,
8-
stream::{Offset as _, Stream as _},
8+
stream::Offset as _,
99
token::{one_of, take_till, take_while},
1010
};
1111

@@ -78,7 +78,7 @@ fn newlines_from(input: &[u8], start: winnow::stream::Checkpoint<&[u8], &[u8]>)
7878
start_input.next_slice(offset).iter().filter(|c| **c == b'\n').count()
7979
}
8080

81-
fn comment<'i>(i: &mut &'i [u8]) -> PResult<Comment<'i>, NomError<&'i [u8]>> {
81+
fn comment<'i>(i: &mut &'i [u8]) -> ModalResult<Comment<'i>, NomError<&'i [u8]>> {
8282
(
8383
one_of([';', '#']),
8484
take_till(0.., |c| c == b'\n').map(|text: &[u8]| Cow::Borrowed(text.as_bstr())),
@@ -94,7 +94,7 @@ fn section<'i>(
9494
i: &mut &'i [u8],
9595
node: &mut ParseNode,
9696
dispatch: &mut dyn FnMut(Event<'i>),
97-
) -> PResult<(), NomError<&'i [u8]>> {
97+
) -> ModalResult<(), NomError<&'i [u8]>> {
9898
let start = i.checkpoint();
9999
let header = section_header(i).map_err(|e| {
100100
i.reset(&start);
@@ -129,11 +129,14 @@ fn section<'i>(
129129
Ok(())
130130
}
131131

132-
fn section_header<'i>(i: &mut &'i [u8]) -> PResult<section::Header<'i>, NomError<&'i [u8]>> {
132+
fn section_header<'i>(i: &mut &'i [u8]) -> ModalResult<section::Header<'i>, NomError<&'i [u8]>> {
133133
// No spaces must be between section name and section start
134134
let name = preceded('[', take_while(1.., is_section_char).map(bstr::ByteSlice::as_bstr)).parse_next(i)?;
135135

136-
if opt(one_of::<_, _, NomError<&[u8]>>(']')).parse_next(i)?.is_some() {
136+
if opt(one_of::<_, _, ErrMode<NomError<&[u8]>>>(']'))
137+
.parse_next(i)?
138+
.is_some()
139+
{
137140
// Either section does not have a subsection or using deprecated
138141
// subsection syntax at this point.
139142
let header = match memchr::memrchr(b'.', name.as_bytes()) {
@@ -150,7 +153,7 @@ fn section_header<'i>(i: &mut &'i [u8]) -> PResult<section::Header<'i>, NomError
150153
};
151154

152155
if header.name.is_empty() {
153-
return Err(winnow::error::ErrMode::from_error_kind(i, ErrorKind::Fail));
156+
return Err(winnow::error::ErrMode::from_input(i));
154157
}
155158
return Ok(header);
156159
}
@@ -169,7 +172,7 @@ fn is_section_char(c: u8) -> bool {
169172
c.is_ascii_alphanumeric() || c == b'-' || c == b'.'
170173
}
171174

172-
fn sub_section<'i>(i: &mut &'i [u8]) -> PResult<Cow<'i, BStr>, NomError<&'i [u8]>> {
175+
fn sub_section<'i>(i: &mut &'i [u8]) -> ModalResult<Cow<'i, BStr>, NomError<&'i [u8]>> {
173176
let mut output = Cow::Borrowed(Default::default());
174177
if let Some(sub) = opt(subsection_subset).parse_next(i)? {
175178
output = Cow::Borrowed(sub.as_bstr());
@@ -181,15 +184,15 @@ fn sub_section<'i>(i: &mut &'i [u8]) -> PResult<Cow<'i, BStr>, NomError<&'i [u8]
181184
Ok(output)
182185
}
183186

184-
fn subsection_subset<'i>(i: &mut &'i [u8]) -> PResult<&'i [u8], NomError<&'i [u8]>> {
187+
fn subsection_subset<'i>(i: &mut &'i [u8]) -> ModalResult<&'i [u8], NomError<&'i [u8]>> {
185188
alt((subsection_unescaped, subsection_escaped_char)).parse_next(i)
186189
}
187190

188-
fn subsection_unescaped<'i>(i: &mut &'i [u8]) -> PResult<&'i [u8], NomError<&'i [u8]>> {
191+
fn subsection_unescaped<'i>(i: &mut &'i [u8]) -> ModalResult<&'i [u8], NomError<&'i [u8]>> {
189192
take_while(1.., is_subsection_unescaped_char).parse_next(i)
190193
}
191194

192-
fn subsection_escaped_char<'i>(i: &mut &'i [u8]) -> PResult<&'i [u8], NomError<&'i [u8]>> {
195+
fn subsection_escaped_char<'i>(i: &mut &'i [u8]) -> ModalResult<&'i [u8], NomError<&'i [u8]>> {
193196
preceded('\\', one_of(is_subsection_escapable_char).take()).parse_next(i)
194197
}
195198

@@ -205,7 +208,7 @@ fn key_value_pair<'i>(
205208
i: &mut &'i [u8],
206209
node: &mut ParseNode,
207210
dispatch: &mut dyn FnMut(Event<'i>),
208-
) -> PResult<(), NomError<&'i [u8]>> {
211+
) -> ModalResult<(), NomError<&'i [u8]>> {
209212
*node = ParseNode::Name;
210213
if let Some(name) = opt(config_name).parse_next(i)? {
211214
dispatch(Event::SectionValueName(section::ValueName(Cow::Borrowed(name))));
@@ -223,7 +226,7 @@ fn key_value_pair<'i>(
223226

224227
/// Parses the config name of a config pair. Assumes the input has already been
225228
/// trimmed of any leading whitespace.
226-
fn config_name<'i>(i: &mut &'i [u8]) -> PResult<&'i BStr, NomError<&'i [u8]>> {
229+
fn config_name<'i>(i: &mut &'i [u8]) -> ModalResult<&'i BStr, NomError<&'i [u8]>> {
227230
(
228231
one_of(|c: u8| c.is_ascii_alphabetic()),
229232
take_while(0.., |c: u8| c.is_ascii_alphanumeric() || c == b'-'),
@@ -233,7 +236,7 @@ fn config_name<'i>(i: &mut &'i [u8]) -> PResult<&'i BStr, NomError<&'i [u8]>> {
233236
.parse_next(i)
234237
}
235238

236-
fn config_value<'i>(i: &mut &'i [u8], dispatch: &mut dyn FnMut(Event<'i>)) -> PResult<(), NomError<&'i [u8]>> {
239+
fn config_value<'i>(i: &mut &'i [u8], dispatch: &mut dyn FnMut(Event<'i>)) -> ModalResult<(), NomError<&'i [u8]>> {
237240
if opt('=').parse_next(i)?.is_some() {
238241
dispatch(Event::KeyValueSeparator);
239242
if let Some(whitespace) = opt(take_spaces1).parse_next(i)? {
@@ -251,7 +254,7 @@ fn config_value<'i>(i: &mut &'i [u8], dispatch: &mut dyn FnMut(Event<'i>)) -> PR
251254

252255
/// Handles parsing of known-to-be values. This function handles both single
253256
/// line values as well as values that are continuations.
254-
fn value_impl<'i>(i: &mut &'i [u8], dispatch: &mut dyn FnMut(Event<'i>)) -> PResult<(), NomError<&'i [u8]>> {
257+
fn value_impl<'i>(i: &mut &'i [u8], dispatch: &mut dyn FnMut(Event<'i>)) -> ModalResult<(), NomError<&'i [u8]>> {
255258
let start_checkpoint = i.checkpoint();
256259
let mut value_start_checkpoint = i.checkpoint();
257260
let mut value_end = None;
@@ -278,17 +281,17 @@ fn value_impl<'i>(i: &mut &'i [u8], dispatch: &mut dyn FnMut(Event<'i>)) -> PRes
278281
let escape_index = escaped_index - 1;
279282
let Some(mut c) = i.next_token() else {
280283
i.reset(&start_checkpoint);
281-
return Err(winnow::error::ErrMode::from_error_kind(i, ErrorKind::Token));
284+
return Err(winnow::error::ErrMode::from_input(i));
282285
};
283286
let mut consumed = 1;
284287
if c == b'\r' {
285288
c = i.next_token().ok_or_else(|| {
286289
i.reset(&start_checkpoint);
287-
winnow::error::ErrMode::from_error_kind(i, ErrorKind::Token)
290+
winnow::error::ErrMode::from_input(i)
288291
})?;
289292
if c != b'\n' {
290293
i.reset(&start_checkpoint);
291-
return Err(winnow::error::ErrMode::from_error_kind(i, ErrorKind::Slice));
294+
return Err(winnow::error::ErrMode::from_input(i));
292295
}
293296
consumed += 1;
294297
}
@@ -313,7 +316,7 @@ fn value_impl<'i>(i: &mut &'i [u8], dispatch: &mut dyn FnMut(Event<'i>)) -> PRes
313316
b'n' | b't' | b'\\' | b'b' | b'"' => {}
314317
_ => {
315318
i.reset(&start_checkpoint);
316-
return Err(winnow::error::ErrMode::from_error_kind(i, ErrorKind::Token));
319+
return Err(winnow::error::ErrMode::from_input(i));
317320
}
318321
}
319322
}
@@ -326,7 +329,7 @@ fn value_impl<'i>(i: &mut &'i [u8], dispatch: &mut dyn FnMut(Event<'i>)) -> PRes
326329
}
327330
if is_in_quotes {
328331
i.reset(&start_checkpoint);
329-
return Err(winnow::error::ErrMode::from_error_kind(i, ErrorKind::Slice));
332+
return Err(winnow::error::ErrMode::from_input(i));
330333
}
331334

332335
let value_end = match value_end {
@@ -360,13 +363,13 @@ fn value_impl<'i>(i: &mut &'i [u8], dispatch: &mut dyn FnMut(Event<'i>)) -> PRes
360363
Ok(())
361364
}
362365

363-
fn take_spaces1<'i>(i: &mut &'i [u8]) -> PResult<&'i BStr, NomError<&'i [u8]>> {
366+
fn take_spaces1<'i>(i: &mut &'i [u8]) -> ModalResult<&'i BStr, NomError<&'i [u8]>> {
364367
take_while(1.., winnow::stream::AsChar::is_space)
365368
.map(bstr::ByteSlice::as_bstr)
366369
.parse_next(i)
367370
}
368371

369-
fn take_newlines1<'i>(i: &mut &'i [u8]) -> PResult<&'i BStr, NomError<&'i [u8]>> {
372+
fn take_newlines1<'i>(i: &mut &'i [u8]) -> ModalResult<&'i BStr, NomError<&'i [u8]>> {
370373
repeat(1..1024, alt(("\r\n", "\n")))
371374
.map(|()| ())
372375
.take()

0 commit comments

Comments
 (0)