Function winnow::branch::permutation

source ·
pub fn permutation<I: Stream, O, E: ParseError<I>, List: Permutation<I, O, E>>(
    l: List
) -> impl Parser<I, O, E>
Expand description

Applies a list of parsers in any order.

Permutation will succeed if all of the child parsers succeeded. It takes as argument a tuple of parsers, and returns a tuple of the parser results.

use winnow::character::{alpha1, digit1};
use winnow::branch::permutation;
fn parser(input: &str) -> IResult<&str, (&str, &str)> {
  permutation((alpha1, digit1)).parse_next(input)
}

// permutation recognizes alphabetic characters then digit
assert_eq!(parser("abc123"), Ok(("", ("abc", "123"))));

// but also in inverse order
assert_eq!(parser("123abc"), Ok(("", ("abc", "123"))));

// it will fail if one of the parsers failed
assert_eq!(parser("abc;"), Err(ErrMode::Backtrack(Error::new(";", ErrorKind::Slice))));

The parsers are applied greedily: if there are multiple unapplied parsers that could parse the next slice of input, the first one is used.

use winnow::branch::permutation;
use winnow::bytes::any;

fn parser(input: &str) -> IResult<&str, (char, char)> {
  permutation((any, 'a')).parse_next(input)
}

// any parses 'b', then char('a') parses 'a'
assert_eq!(parser("ba"), Ok(("", ('b', 'a'))));

// any parses 'a', then char('a') fails on 'b',
// even though char('a') followed by any would succeed
assert_eq!(parser("ab"), Err(ErrMode::Backtrack(Error::new("b", ErrorKind::Verify))));