Skip to main content

unordered_seq

Macro unordered_seq 

Source
macro_rules! unordered_seq {
    ($($name: ident)::* { $($fields: tt)* }) => { ... };
    (( $($fields: tt)* )) => { ... };
    ($($name: ident)::* ( $($fields: tt)* )) => { ... };
    ($($fields: tt)*) => { ... };
}
Expand description

Initialize a struct or tuple out of an unordered sequences of parsers

Unlike normal struct initialization syntax:

  • _ fields can exist to run a parser but ignore the result
  • Parse results for a field can later be referenced using the field name

Unlike normal tuple initialization syntax:

  • Struct-style initialization ({ 0: _, 1: _}) is not supported
  • _: <parser> fields can exist to run a parser but ignore the result

To stop on an error, rather than trying further permutations, see cut_err ([example][crate::_tutorial::chapter_7]).

ยงExample

use winnow::ascii::{alpha1, digit1};
use winnow::combinator::unordered_seq;
fn parser<'i>(input: &mut &'i str) -> ModalResult<(&'i str, &'i str)> {
  unordered_seq!((alpha1, digit1)).parse_next(input)
}

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

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

// it will fail if one of the parsers failed
assert!(parser.parse_peek("abc;").is_err());

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::combinator::unordered_seq;
use winnow::token::any;

fn parser(input: &mut &str) -> ModalResult<(char, char)> {
  unordered_seq!((any, 'a')).parse_next(input)
}

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

// any parses 'a', then char('a') fails on 'b',
// even though char('a') followed by any would succeed
assert!(parser.parse_peek("ab").is_err());