diff options
Diffstat (limited to 'vendor/winnow/examples/ndjson/parser.rs')
-rw-r--r-- | vendor/winnow/examples/ndjson/parser.rs | 100 |
1 files changed, 55 insertions, 45 deletions
diff --git a/vendor/winnow/examples/ndjson/parser.rs b/vendor/winnow/examples/ndjson/parser.rs index 2a60952e3..aaa5c9346 100644 --- a/vendor/winnow/examples/ndjson/parser.rs +++ b/vendor/winnow/examples/ndjson/parser.rs @@ -9,7 +9,7 @@ use winnow::{ combinator::cut_err, combinator::{delimited, preceded, separated_pair, terminated}, combinator::{fold_repeat, separated0}, - error::{ContextError, ParseError}, + error::{AddContext, ParserError}, stream::Partial, token::{any, none_of, take, take_while}, }; @@ -27,9 +27,9 @@ pub enum JsonValue { /// Use `Partial` to cause `ErrMode::Incomplete` while parsing pub type Stream<'i> = Partial<&'i str>; -pub fn ndjson<'i, E: ParseError<Stream<'i>> + ContextError<Stream<'i>, &'static str>>( - input: Stream<'i>, -) -> IResult<Stream<'i>, Option<JsonValue>, E> { +pub fn ndjson<'i, E: ParserError<Stream<'i>> + AddContext<Stream<'i>, &'static str>>( + input: &mut Stream<'i>, +) -> PResult<Option<JsonValue>, E> { alt(( terminated(delimited(ws, json_value, ws), line_ending).map(Some), line_ending.value(None), @@ -41,9 +41,9 @@ pub fn ndjson<'i, E: ParseError<Stream<'i>> + ContextError<Stream<'i>, &'static /// `alt` is a combinator that tries multiple parsers one by one, until /// one of them succeeds -fn json_value<'i, E: ParseError<Stream<'i>> + ContextError<Stream<'i>, &'static str>>( - input: Stream<'i>, -) -> IResult<Stream<'i>, JsonValue, E> { +fn json_value<'i, E: ParserError<Stream<'i>> + AddContext<Stream<'i>, &'static str>>( + input: &mut Stream<'i>, +) -> PResult<JsonValue, E> { // `alt` combines the each value parser. It returns the result of the first // successful parser, or an error alt(( @@ -60,7 +60,7 @@ fn json_value<'i, E: ParseError<Stream<'i>> + ContextError<Stream<'i>, &'static /// `tag(string)` generates a parser that recognizes the argument string. /// /// This also shows returning a sub-slice of the original input -fn null<'i, E: ParseError<Stream<'i>>>(input: Stream<'i>) -> IResult<Stream<'i>, &'i str, E> { +fn null<'i, E: ParserError<Stream<'i>>>(input: &mut Stream<'i>) -> PResult<&'i str, E> { // This is a parser that returns `"null"` if it sees the string "null", and // an error otherwise "null".parse_next(input) @@ -68,7 +68,7 @@ fn null<'i, E: ParseError<Stream<'i>>>(input: Stream<'i>) -> IResult<Stream<'i>, /// We can combine `tag` with other functions, like `value` which returns a given constant value on /// success. -fn boolean<'i, E: ParseError<Stream<'i>>>(input: Stream<'i>) -> IResult<Stream<'i>, bool, E> { +fn boolean<'i, E: ParserError<Stream<'i>>>(input: &mut Stream<'i>) -> PResult<bool, E> { // This is a parser that returns `true` if it sees the string "true", and // an error otherwise let parse_true = "true".value(true); @@ -82,9 +82,9 @@ fn boolean<'i, E: ParseError<Stream<'i>>>(input: Stream<'i>) -> IResult<Stream<' /// This parser gathers all `char`s up into a `String`with a parse to recognize the double quote /// character, before the string (using `preceded`) and after the string (using `terminated`). -fn string<'i, E: ParseError<Stream<'i>> + ContextError<Stream<'i>, &'static str>>( - input: Stream<'i>, -) -> IResult<Stream<'i>, String, E> { +fn string<'i, E: ParserError<Stream<'i>> + AddContext<Stream<'i>, &'static str>>( + input: &mut Stream<'i>, +) -> PResult<String, E> { preceded( '\"', // `cut_err` transforms an `ErrMode::Backtrack(e)` to `ErrMode::Cut(e)`, signaling to @@ -107,8 +107,8 @@ fn string<'i, E: ParseError<Stream<'i>> + ContextError<Stream<'i>, &'static str> /// You can mix the above declarative parsing with an imperative style to handle more unique cases, /// like escaping -fn character<'i, E: ParseError<Stream<'i>>>(input: Stream<'i>) -> IResult<Stream<'i>, char, E> { - let (input, c) = none_of("\"").parse_next(input)?; +fn character<'i, E: ParserError<Stream<'i>>>(input: &mut Stream<'i>) -> PResult<char, E> { + let c = none_of('"').parse_next(input)?; if c == '\\' { alt(( any.verify_map(|c| { @@ -126,13 +126,11 @@ fn character<'i, E: ParseError<Stream<'i>>>(input: Stream<'i>) -> IResult<Stream )) .parse_next(input) } else { - Ok((input, c)) + Ok(c) } } -fn unicode_escape<'i, E: ParseError<Stream<'i>>>( - input: Stream<'i>, -) -> IResult<Stream<'i>, char, E> { +fn unicode_escape<'i, E: ParserError<Stream<'i>>>(input: &mut Stream<'i>) -> PResult<char, E> { alt(( // Not a surrogate u16_hex @@ -154,7 +152,7 @@ fn unicode_escape<'i, E: ParseError<Stream<'i>>>( .parse_next(input) } -fn u16_hex<'i, E: ParseError<Stream<'i>>>(input: Stream<'i>) -> IResult<Stream<'i>, u16, E> { +fn u16_hex<'i, E: ParserError<Stream<'i>>>(input: &mut Stream<'i>) -> PResult<u16, E> { take(4usize) .verify_map(|s| u16::from_str_radix(s, 16).ok()) .parse_next(input) @@ -164,9 +162,9 @@ fn u16_hex<'i, E: ParseError<Stream<'i>>>(input: Stream<'i>) -> IResult<Stream<' /// accumulating results in a `Vec`, until it encounters an error. /// If you want more control on the parser application, check out the `iterator` /// combinator (cf `examples/iterator.rs`) -fn array<'i, E: ParseError<Stream<'i>> + ContextError<Stream<'i>, &'static str>>( - input: Stream<'i>, -) -> IResult<Stream<'i>, Vec<JsonValue>, E> { +fn array<'i, E: ParserError<Stream<'i>> + AddContext<Stream<'i>, &'static str>>( + input: &mut Stream<'i>, +) -> PResult<Vec<JsonValue>, E> { preceded( ('[', ws), cut_err(terminated(separated0(json_value, (ws, ',', ws)), (ws, ']'))), @@ -175,9 +173,9 @@ fn array<'i, E: ParseError<Stream<'i>> + ContextError<Stream<'i>, &'static str>> .parse_next(input) } -fn object<'i, E: ParseError<Stream<'i>> + ContextError<Stream<'i>, &'static str>>( - input: Stream<'i>, -) -> IResult<Stream<'i>, HashMap<String, JsonValue>, E> { +fn object<'i, E: ParserError<Stream<'i>> + AddContext<Stream<'i>, &'static str>>( + input: &mut Stream<'i>, +) -> PResult<HashMap<String, JsonValue>, E> { preceded( ('{', ws), cut_err(terminated(separated0(key_value, (ws, ',', ws)), (ws, '}'))), @@ -186,22 +184,22 @@ fn object<'i, E: ParseError<Stream<'i>> + ContextError<Stream<'i>, &'static str> .parse_next(input) } -fn key_value<'i, E: ParseError<Stream<'i>> + ContextError<Stream<'i>, &'static str>>( - input: Stream<'i>, -) -> IResult<Stream<'i>, (String, JsonValue), E> { +fn key_value<'i, E: ParserError<Stream<'i>> + AddContext<Stream<'i>, &'static str>>( + input: &mut Stream<'i>, +) -> PResult<(String, JsonValue), E> { separated_pair(string, cut_err((ws, ':', ws)), json_value).parse_next(input) } /// Parser combinators are constructed from the bottom up: /// first we write parsers for the smallest elements (here a space character), /// then we'll combine them in larger parsers -fn ws<'i, E: ParseError<Stream<'i>>>(input: Stream<'i>) -> IResult<Stream<'i>, &'i str, E> { +fn ws<'i, E: ParserError<Stream<'i>>>(input: &mut Stream<'i>) -> PResult<&'i str, E> { // Combinators like `take_while` return a function. That function is the // parser,to which we can pass the input take_while(0.., WS).parse_next(input) } -const WS: &str = " \t"; +const WS: &[char] = &[' ', '\t']; #[cfg(test)] mod test { @@ -211,20 +209,20 @@ mod test { #[allow(clippy::useless_attribute)] #[allow(dead_code)] // its dead for benches - type Error<'i> = winnow::error::Error<Partial<&'i str>>; + type Error<'i> = winnow::error::InputError<Partial<&'i str>>; #[test] fn json_string() { assert_eq!( - string::<Error<'_>>(Partial::new("\"\"")), + string::<Error<'_>>.parse_peek(Partial::new("\"\"")), Ok((Partial::new(""), "".to_string())) ); assert_eq!( - string::<Error<'_>>(Partial::new("\"abc\"")), + string::<Error<'_>>.parse_peek(Partial::new("\"abc\"")), Ok((Partial::new(""), "abc".to_string())) ); assert_eq!( - string::<Error<'_>>(Partial::new( + string::<Error<'_>>.parse_peek(Partial::new( "\"abc\\\"\\\\\\/\\b\\f\\n\\r\\t\\u0001\\u2014\u{2014}def\"" )), Ok(( @@ -233,17 +231,29 @@ mod test { )), ); assert_eq!( - string::<Error<'_>>(Partial::new("\"\\uD83D\\uDE10\"")), + string::<Error<'_>>.parse_peek(Partial::new("\"\\uD83D\\uDE10\"")), Ok((Partial::new(""), "😐".to_string())) ); - assert!(string::<Error<'_>>(Partial::new("\"")).is_err()); - assert!(string::<Error<'_>>(Partial::new("\"abc")).is_err()); - assert!(string::<Error<'_>>(Partial::new("\"\\\"")).is_err()); - assert!(string::<Error<'_>>(Partial::new("\"\\u123\"")).is_err()); - assert!(string::<Error<'_>>(Partial::new("\"\\uD800\"")).is_err()); - assert!(string::<Error<'_>>(Partial::new("\"\\uD800\\uD800\"")).is_err()); - assert!(string::<Error<'_>>(Partial::new("\"\\uDC00\"")).is_err()); + assert!(string::<Error<'_>>.parse_peek(Partial::new("\"")).is_err()); + assert!(string::<Error<'_>> + .parse_peek(Partial::new("\"abc")) + .is_err()); + assert!(string::<Error<'_>> + .parse_peek(Partial::new("\"\\\"")) + .is_err()); + assert!(string::<Error<'_>> + .parse_peek(Partial::new("\"\\u123\"")) + .is_err()); + assert!(string::<Error<'_>> + .parse_peek(Partial::new("\"\\uD800\"")) + .is_err()); + assert!(string::<Error<'_>> + .parse_peek(Partial::new("\"\\uD800\\uD800\"")) + .is_err()); + assert!(string::<Error<'_>> + .parse_peek(Partial::new("\"\\uDC00\"")) + .is_err()); } #[test] @@ -263,7 +273,7 @@ mod test { ); assert_eq!( - ndjson::<Error<'_>>(Partial::new(input)), + ndjson::<Error<'_>>.parse_peek(Partial::new(input)), Ok((Partial::new(""), Some(expected))) ); } @@ -278,7 +288,7 @@ mod test { let expected = Array(vec![Num(42.0), Str("x".to_string())]); assert_eq!( - ndjson::<Error<'_>>(Partial::new(input)), + ndjson::<Error<'_>>.parse_peek(Partial::new(input)), Ok((Partial::new(""), Some(expected))) ); } @@ -291,7 +301,7 @@ mod test { "#; assert_eq!( - ndjson::<Error<'_>>(Partial::new(input)), + ndjson::<Error<'_>>.parse_peek(Partial::new(input)), Ok(( Partial::new(""), Some(Object( |