pub fn take_while<Set, Input, Error>(
occurrences: impl Into<Range>,
set: Set,
) -> impl Parser<Input, <Input as Stream>::Slice, Error>where
Input: StreamIsPartial + Stream,
Set: ContainsToken<<Input as Stream>::Token>,
Error: ParserError<Input>,
Expand description
Recognize the longest (m <= len <= n) input slice that matches a set of tokens
It will return an ErrMode::Backtrack(_)
if the set of tokens wasn’t met or is out
of range (m <= len <= n).
[Partial version][crate::_topic::partial] will return a ErrMode::Incomplete(Needed::new(1))
if a member of the set of tokens reaches the end of the input or is too short.
To take a series of tokens, use repeat
to Accumulate
into a ()
and then Parser::take
.
§Effective Signature
Assuming you are parsing a &str
Stream with 0..
or 1..
ranges:
pub fn take_while<'i>(occurrences: RangeFrom<usize>, set: impl ContainsToken<char>) -> impl Parser<&'i str, &'i str, ContextError>
§Example
Zero or more tokens:
use winnow::token::take_while;
use winnow::stream::AsChar;
fn alpha<'i>(s: &mut &'i [u8]) -> ModalResult<&'i [u8]> {
take_while(0.., AsChar::is_alpha).parse_next(s)
}
assert_eq!(alpha.parse_peek(b"latin123"), Ok((&b"123"[..], &b"latin"[..])));
assert_eq!(alpha.parse_peek(b"12345"), Ok((&b"12345"[..], &b""[..])));
assert_eq!(alpha.parse_peek(b"latin"), Ok((&b""[..], &b"latin"[..])));
assert_eq!(alpha.parse_peek(b""), Ok((&b""[..], &b""[..])));
use winnow::token::take_while;
use winnow::stream::AsChar;
fn alpha<'i>(s: &mut Partial<&'i [u8]>) -> ModalResult<&'i [u8]> {
take_while(0.., AsChar::is_alpha).parse_next(s)
}
assert_eq!(alpha.parse_peek(Partial::new(b"latin123")), Ok((Partial::new(&b"123"[..]), &b"latin"[..])));
assert_eq!(alpha.parse_peek(Partial::new(b"12345")), Ok((Partial::new(&b"12345"[..]), &b""[..])));
assert_eq!(alpha.parse_peek(Partial::new(b"latin")), Err(ErrMode::Incomplete(Needed::new(1))));
assert_eq!(alpha.parse_peek(Partial::new(b"")), Err(ErrMode::Incomplete(Needed::new(1))));
One or more tokens:
use winnow::token::take_while;
use winnow::stream::AsChar;
fn alpha<'i>(s: &mut &'i [u8]) -> ModalResult<&'i [u8]> {
take_while(1.., AsChar::is_alpha).parse_next(s)
}
assert_eq!(alpha.parse_peek(b"latin123"), Ok((&b"123"[..], &b"latin"[..])));
assert_eq!(alpha.parse_peek(b"latin"), Ok((&b""[..], &b"latin"[..])));
assert!(alpha.parse_peek(b"12345").is_err());
fn hex<'i>(s: &mut &'i str) -> ModalResult<&'i str> {
take_while(1.., ('0'..='9', 'A'..='F')).parse_next(s)
}
assert_eq!(hex.parse_peek("123 and voila"), Ok((" and voila", "123")));
assert_eq!(hex.parse_peek("DEADBEEF and others"), Ok((" and others", "DEADBEEF")));
assert_eq!(hex.parse_peek("BADBABEsomething"), Ok(("something", "BADBABE")));
assert_eq!(hex.parse_peek("D15EA5E"), Ok(("", "D15EA5E")));
assert!(hex.parse_peek("").is_err());
use winnow::token::take_while;
use winnow::stream::AsChar;
fn alpha<'i>(s: &mut Partial<&'i [u8]>) -> ModalResult<&'i [u8]> {
take_while(1.., AsChar::is_alpha).parse_next(s)
}
assert_eq!(alpha.parse_peek(Partial::new(b"latin123")), Ok((Partial::new(&b"123"[..]), &b"latin"[..])));
assert_eq!(alpha.parse_peek(Partial::new(b"latin")), Err(ErrMode::Incomplete(Needed::new(1))));
assert!(alpha.parse_peek(Partial::new(b"12345")).is_err());
fn hex<'i>(s: &mut Partial<&'i str>) -> ModalResult<&'i str> {
take_while(1.., ('0'..='9', 'A'..='F')).parse_next(s)
}
assert_eq!(hex.parse_peek(Partial::new("123 and voila")), Ok((Partial::new(" and voila"), "123")));
assert_eq!(hex.parse_peek(Partial::new("DEADBEEF and others")), Ok((Partial::new(" and others"), "DEADBEEF")));
assert_eq!(hex.parse_peek(Partial::new("BADBABEsomething")), Ok((Partial::new("something"), "BADBABE")));
assert_eq!(hex.parse_peek(Partial::new("D15EA5E")), Err(ErrMode::Incomplete(Needed::new(1))));
assert_eq!(hex.parse_peek(Partial::new("")), Err(ErrMode::Incomplete(Needed::new(1))));
Arbitrary amount of tokens:
use winnow::token::take_while;
use winnow::stream::AsChar;
fn short_alpha<'i>(s: &mut &'i [u8]) -> ModalResult<&'i [u8]> {
take_while(3..=6, AsChar::is_alpha).parse_next(s)
}
assert_eq!(short_alpha.parse_peek(b"latin123"), Ok((&b"123"[..], &b"latin"[..])));
assert_eq!(short_alpha.parse_peek(b"lengthy"), Ok((&b"y"[..], &b"length"[..])));
assert_eq!(short_alpha.parse_peek(b"latin"), Ok((&b""[..], &b"latin"[..])));
assert!(short_alpha.parse_peek(b"ed").is_err());
assert!(short_alpha.parse_peek(b"12345").is_err());
use winnow::token::take_while;
use winnow::stream::AsChar;
fn short_alpha<'i>(s: &mut Partial<&'i [u8]>) -> ModalResult<&'i [u8]> {
take_while(3..=6, AsChar::is_alpha).parse_next(s)
}
assert_eq!(short_alpha.parse_peek(Partial::new(b"latin123")), Ok((Partial::new(&b"123"[..]), &b"latin"[..])));
assert_eq!(short_alpha.parse_peek(Partial::new(b"lengthy")), Ok((Partial::new(&b"y"[..]), &b"length"[..])));
assert_eq!(short_alpha.parse_peek(Partial::new(b"latin")), Err(ErrMode::Incomplete(Needed::new(1))));
assert_eq!(short_alpha.parse_peek(Partial::new(b"ed")), Err(ErrMode::Incomplete(Needed::new(1))));
assert!(short_alpha.parse_peek(Partial::new(b"12345")).is_err());