Macro nom::permutation [] [src]

macro_rules! permutation {
    ($i:expr, $($rest:tt)*) => { ... };
}

permutation!(I -> IResult<I,A>, I -> IResult<I,B>, ... I -> IResult<I,X> ) => I -> IResult<I, (A,B,...X)> applies its sub parsers in a sequence, but independent from their order this parser will only succeed if all of its sub parsers succeed

the tuple of results is in the same order as the parsers are declared

named!(perm<(&[u8], &[u8], &[u8])>,
  permutation!(tag!("abcd"), tag!("efg"), tag!("hi"))
);

// whatever the order, if the parser succeeds, each
// tag should have matched correctly
let expected = (&b"abcd"[..], &b"efg"[..], &b"hi"[..]);

let a = &b"abcdefghijk"[..];
assert_eq!(perm(a), Ok((&b"jk"[..], expected)));
let b = &b"efgabcdhijkl"[..];
assert_eq!(perm(b), Ok((&b"jkl"[..], expected)));
let c = &b"hiefgabcdjklm"[..];
assert_eq!(perm(c), Ok((&b"jklm"[..], expected)));

let d = &b"efgxyzabcdefghi"[..];
assert_eq!(perm(d), Err(Err::Error(error_node_position!(&b"efgxyzabcdefghi"[..], ErrorKind::Permutation,
  error_position!(&b"xyzabcdefghi"[..], ErrorKind::Permutation)))));

let e = &b"efgabc"[..];
assert_eq!(perm(e), Err(Err::Incomplete(Needed::Size(4))));

If one of the child parsers is followed by a ?, that parser is now optional:

named!(perm<&str, (Option<&str>, &str, &str)>,
  permutation!(tag!("abcd")?, tag!("efg"), tag!("hi"))
);

// whatever the order, if the parser succeeds, each
// tag should have matched correctly
let expected = (Some("abcd"), "efg", "hi");

let a = "abcdefghijk";
assert_eq!(perm(a), Ok(("jk", expected)));
let b = "efgabcdhijkl";
assert_eq!(perm(b), Ok(("jkl", expected)));
let c = "hiefgabcdjklm";
assert_eq!(perm(c), Ok(("jklm", expected)));

// if `abcd` is missing:
let expected = (None, "efg", "hi");

let a = "efghijk";
assert_eq!(perm(a), Ok(("jk", expected)));
let b = "efghijkl";
assert_eq!(perm(b), Ok(("jkl", expected)));
let c = "hiefgjklm";
assert_eq!(perm(c), Ok(("jklm", expected)));

let e = "efgabc";
assert_eq!(perm(e), Err(Err::Incomplete(Needed::Size(4))));