pub struct Repeat<P, I, O, C, E>{ /* private fields */ }
Implementations§
Source§impl<ParseNext, Input, Output, Error> Repeat<ParseNext, Input, Output, (), Error>
impl<ParseNext, Input, Output, Error> Repeat<ParseNext, Input, Output, (), Error>
Sourcepub fn fold<Init, Op, Result>(
self,
init: Init,
op: Op,
) -> impl Parser<Input, Result, Error>
pub fn fold<Init, Op, Result>( self, init: Init, op: Op, ) -> impl Parser<Input, Result, Error>
Repeats the embedded parser, calling op
to gather the results
This stops before n
when the parser returns ErrMode::Backtrack
. To instead chain an error up, see
cut_err
.
§Arguments
init
A function returning the initial value.op
The function that combines a result off
with the current accumulator.
Warning: If the parser passed to fold
accepts empty inputs
(like alpha0
or digit0
), fold_repeat
will return an error,
to prevent going into an infinite loop.
§Example
Zero or more repetitions:
use winnow::combinator::repeat;
fn parser<'i>(s: &mut &'i str) -> ModalResult<Vec<&'i str>> {
repeat(
0..,
"abc"
).fold(
Vec::new,
|mut acc: Vec<_>, item| {
acc.push(item);
acc
}
).parse_next(s)
}
assert_eq!(parser.parse_peek("abcabc"), Ok(("", vec!["abc", "abc"])));
assert_eq!(parser.parse_peek("abc123"), Ok(("123", vec!["abc"])));
assert_eq!(parser.parse_peek("123123"), Ok(("123123", vec![])));
assert_eq!(parser.parse_peek(""), Ok(("", vec![])));
One or more repetitions:
use winnow::combinator::repeat;
fn parser<'i>(s: &mut &'i str) -> ModalResult<Vec<&'i str>> {
repeat(
1..,
"abc",
).fold(
Vec::new,
|mut acc: Vec<_>, item| {
acc.push(item);
acc
}
).parse_next(s)
}
assert_eq!(parser.parse_peek("abcabc"), Ok(("", vec!["abc", "abc"])));
assert_eq!(parser.parse_peek("abc123"), Ok(("123", vec!["abc"])));
assert!(parser.parse_peek("123123").is_err());
assert!(parser.parse_peek("").is_err());
Arbitrary number of repetitions:
use winnow::combinator::repeat;
fn parser<'i>(s: &mut &'i str) -> ModalResult<Vec<&'i str>> {
repeat(
0..=2,
"abc",
).fold(
Vec::new,
|mut acc: Vec<_>, item| {
acc.push(item);
acc
}
).parse_next(s)
}
assert_eq!(parser.parse_peek("abcabc"), Ok(("", vec!["abc", "abc"])));
assert_eq!(parser.parse_peek("abc123"), Ok(("123", vec!["abc"])));
assert_eq!(parser.parse_peek("123123"), Ok(("123123", vec![])));
assert_eq!(parser.parse_peek(""), Ok(("", vec![])));
assert_eq!(parser.parse_peek("abcabcabc"), Ok(("abc", vec!["abc", "abc"])));
Sourcepub fn verify_fold<Init, Op, Result>(
self,
init: Init,
op: Op,
) -> impl Parser<Input, Result, Error>
pub fn verify_fold<Init, Op, Result>( self, init: Init, op: Op, ) -> impl Parser<Input, Result, Error>
Akin to Repeat::fold
, but for containers that can reject an element.
This stops before n
when the parser returns ErrMode::Backtrack
. To instead chain an error up, see
cut_err
. Additionally, if the fold function returns None
, the parser will
stop and return an error.
§Arguments
init
A function returning the initial value.op
The function that combines a result off
with the current accumulator.
Warning: If the parser passed to repeat
accepts empty inputs
(like alpha0
or digit0
), verify_fold
will return an error,
to prevent going into an infinite loop.
§Example
Guaranteeing that the input had unique elements:
use winnow::combinator::repeat;
use std::collections::HashSet;
fn parser<'i>(s: &mut &'i str) -> ModalResult<HashSet<&'i str>> {
repeat(
0..,
"abc"
).verify_fold(
HashSet::new,
|mut acc: HashSet<_>, item| {
if acc.insert(item) {
Some(acc)
} else {
None
}
}
).parse_next(s)
}
assert_eq!(parser.parse_peek("abc"), Ok(("", HashSet::from(["abc"]))));
assert!(parser.parse_peek("abcabc").is_err());
assert_eq!(parser.parse_peek("abc123"), Ok(("123", HashSet::from(["abc"]))));
assert_eq!(parser.parse_peek("123123"), Ok(("123123", HashSet::from([]))));
assert_eq!(parser.parse_peek(""), Ok(("", HashSet::from([]))));
Sourcepub fn try_fold<Init, Op, OpError, Result>(
self,
init: Init,
op: Op,
) -> impl Parser<Input, Result, Error>where
Init: FnMut() -> Result,
Op: FnMut(Result, Output) -> Result<Result, OpError>,
Error: FromExternalError<Input, OpError>,
pub fn try_fold<Init, Op, OpError, Result>(
self,
init: Init,
op: Op,
) -> impl Parser<Input, Result, Error>where
Init: FnMut() -> Result,
Op: FnMut(Result, Output) -> Result<Result, OpError>,
Error: FromExternalError<Input, OpError>,
Akin to Repeat::fold
, but for containers that can error when an element is accumulated.
This stops before n
when the parser returns ErrMode::Backtrack
. To instead chain an error up, see
cut_err
. Additionally, if the fold function returns an error, the parser will
stop and return it.
§Arguments
init
A function returning the initial value.op
The function that combines a result off
with the current accumulator.
Warning: If the parser passed to repeat
accepts empty inputs
(like alpha0
or digit0
), try_fold
will return an error,
to prevent going into an infinite loop.
§Example
Writing the output to a vector of bytes:
use winnow::combinator::repeat;
use std::io::Write;
use std::io::Error;
fn parser(s: &mut &str) -> ModalResult<Vec<u8>> {
repeat(
0..,
"abc"
).try_fold(
Vec::new,
|mut acc, item: &str| -> Result<_, Error> {
acc.write(item.as_bytes())?;
Ok(acc)
}
).parse_next(s)
}
assert_eq!(parser.parse_peek("abc"), Ok(("", b"abc".to_vec())));
assert_eq!(parser.parse_peek("abc123"), Ok(("123", b"abc".to_vec())));
assert_eq!(parser.parse_peek("123123"), Ok(("123123", vec![])));
assert_eq!(parser.parse_peek(""), Ok(("", vec![])));
Trait Implementations§
Source§impl<P, I, O, C, E> Parser<I, C, E> for Repeat<P, I, O, C, E>
impl<P, I, O, C, E> Parser<I, C, E> for Repeat<P, I, O, C, E>
Source§fn parse_next(&mut self, i: &mut I) -> Result<C, E>
fn parse_next(&mut self, i: &mut I) -> Result<C, E>
Source§fn parse(
&mut self,
input: I,
) -> Result<O, ParseError<I, <E as ParserError<I>>::Inner>>where
Self: Sized,
I: Stream + StreamIsPartial,
E: ParserError<I>,
<E as ParserError<I>>::Inner: ParserError<I>,
fn parse(
&mut self,
input: I,
) -> Result<O, ParseError<I, <E as ParserError<I>>::Inner>>where
Self: Sized,
I: Stream + StreamIsPartial,
E: ParserError<I>,
<E as ParserError<I>>::Inner: ParserError<I>,
input
, generating O
from itSource§fn parse_peek(&mut self, input: I) -> Result<(I, O), E>
fn parse_peek(&mut self, input: I) -> Result<(I, O), E>
Source§fn by_ref(&mut self) -> ByRef<'_, Self, I, O, E>where
Self: Sized,
fn by_ref(&mut self) -> ByRef<'_, Self, I, O, E>where
Self: Sized,
&mut Self
as a parser Read moreSource§fn default_value<O2>(self) -> DefaultValue<Self, I, O, O2, E>
fn default_value<O2>(self) -> DefaultValue<Self, I, O, O2, E>
Source§fn void(self) -> Void<Self, I, O, E>where
Self: Sized,
fn void(self) -> Void<Self, I, O, E>where
Self: Sized,
Parser
Read moreSource§fn output_into<O2>(self) -> OutputInto<Self, I, O, O2, E>
fn output_into<O2>(self) -> OutputInto<Self, I, O, O2, E>
std::convert::From
Read moreSource§fn with_taken(self) -> WithTaken<Self, I, O, E>
fn with_taken(self) -> WithTaken<Self, I, O, E>
Source§fn span(self) -> Span<Self, I, O, E>
fn span(self) -> Span<Self, I, O, E>
Source§fn with_span(self) -> WithSpan<Self, I, O, E>
fn with_span(self) -> WithSpan<Self, I, O, E>
Source§fn map<G, O2>(self, map: G) -> Map<Self, G, I, O, O2, E>
fn map<G, O2>(self, map: G) -> Map<Self, G, I, O, O2, E>
Source§fn try_map<G, O2, E2>(self, map: G) -> TryMap<Self, G, I, O, O2, E, E2>where
Self: Sized,
G: FnMut(O) -> Result<O2, E2>,
I: Stream,
E: FromExternalError<I, E2> + ParserError<I>,
fn try_map<G, O2, E2>(self, map: G) -> TryMap<Self, G, I, O, O2, E, E2>where
Self: Sized,
G: FnMut(O) -> Result<O2, E2>,
I: Stream,
E: FromExternalError<I, E2> + ParserError<I>,
Result
over the output of a parser. Read moreSource§fn verify_map<G, O2>(self, map: G) -> VerifyMap<Self, G, I, O, O2, E>
fn verify_map<G, O2>(self, map: G) -> VerifyMap<Self, G, I, O, O2, E>
Source§fn flat_map<G, H, O2>(self, map: G) -> FlatMap<Self, G, H, I, O, O2, E>
fn flat_map<G, H, O2>(self, map: G) -> FlatMap<Self, G, H, I, O, O2, E>
Source§fn and_then<G, O2>(self, inner: G) -> AndThen<Self, G, I, O, O2, E>
fn and_then<G, O2>(self, inner: G) -> AndThen<Self, G, I, O, O2, E>
Source§fn parse_to<O2>(self) -> ParseTo<Self, I, O, O2, E>
fn parse_to<O2>(self) -> ParseTo<Self, I, O, O2, E>
std::str::FromStr
to the output of the parser Read more