Function winnow::combinator::repeat
source · pub fn repeat<I, O, C, E, F>(
range: impl Into<Range>,
f: F,
) -> impl Parser<I, C, E>
Expand description
Accumulate
the output of a parser into a container, like Vec
This stops before n
when the parser returns ErrMode::Backtrack
. To instead chain an error up, see
cut_err
.
§Arguments
m
The minimum number of iterations.n
The maximum number of iterations.f
The parser to apply.
To recognize a series of tokens, Accumulate
into a ()
and then Parser::recognize
.
Warning: If the parser passed to repeat
accepts empty inputs
(like alpha0
or digit0
), repeat
will return an error,
to prevent going into an infinite loop.
§Example
Zero or more reptitions:
use winnow::combinator::repeat;
use winnow::token::tag;
fn parser(s: &str) -> IResult<&str, Vec<&str>> {
repeat(0.., "abc").parse_peek(s)
}
assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"])));
assert_eq!(parser("abc123"), Ok(("123", vec!["abc"])));
assert_eq!(parser("123123"), Ok(("123123", vec![])));
assert_eq!(parser(""), Ok(("", vec![])));
One or more reptitions:
use winnow::combinator::repeat;
use winnow::token::tag;
fn parser(s: &str) -> IResult<&str, Vec<&str>> {
repeat(1.., "abc").parse_peek(s)
}
assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"])));
assert_eq!(parser("abc123"), Ok(("123", vec!["abc"])));
assert_eq!(parser("123123"), Err(ErrMode::Backtrack(InputError::new("123123", ErrorKind::Tag))));
assert_eq!(parser(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Tag))));
Fixed number of repeitions:
use winnow::combinator::repeat;
use winnow::token::tag;
fn parser(s: &str) -> IResult<&str, Vec<&str>> {
repeat(2, "abc").parse_peek(s)
}
assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"])));
assert_eq!(parser("abc123"), Err(ErrMode::Backtrack(InputError::new("123", ErrorKind::Tag))));
assert_eq!(parser("123123"), Err(ErrMode::Backtrack(InputError::new("123123", ErrorKind::Tag))));
assert_eq!(parser(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Tag))));
assert_eq!(parser("abcabcabc"), Ok(("abc", vec!["abc", "abc"])));
Arbitrary reptitions:
use winnow::combinator::repeat;
use winnow::token::tag;
fn parser(s: &str) -> IResult<&str, Vec<&str>> {
repeat(0..=2, "abc").parse_peek(s)
}
assert_eq!(parser("abcabc"), Ok(("", vec!["abc", "abc"])));
assert_eq!(parser("abc123"), Ok(("123", vec!["abc"])));
assert_eq!(parser("123123"), Ok(("123123", vec![])));
assert_eq!(parser(""), Ok(("", vec![])));
assert_eq!(parser("abcabcabc"), Ok(("abc", vec!["abc", "abc"])));