nom::chain!
[−]
[src]
macro_rules! chain { ($i:expr, $($rest:tt)*) => { ... }; }
chain!(I->IResult<I,A> ~ I->IResult<I,B> ~ ... I->IResult<I,X> , || { return O } ) => I -> IResult<I, O>
chains parsers and assemble the results through a closure
the input type I must implement nom::InputLength
this combinator will count how much data is consumed by every child parser and take it into account if
there is not enough data
#[derive(PartialEq,Eq,Debug)] struct B { a: u8, b: Option<u8> } named!(y, tag!("efgh")); fn ret_int(i:&[u8]) -> IResult<&[u8], u8> { Done(i, 1) } named!(ret_y<&[u8], u8>, map!(y, |_| 1)); // return 1 if the "efgh" tag is found named!(z<&[u8], B>, chain!( tag!("abcd") ~ // the '~' character is used as separator aa: ret_int ~ // the result of that parser will be used in the closure tag!("abcd")? ~ // this parser is optional bb: ret_y? , // the result of that parser is an option // the last parser in the chain is followed by a ',' ||{B{a: aa, b: bb}} ) ); // the first "abcd" tag is not present, we have an error let r1 = z(&b"efgh"[..]); assert_eq!(r1, Error(Position(ErrorKind::Tag,&b"efgh"[..]))); // everything is present, everything is parsed let r2 = z(&b"abcdabcdefgh"[..]); assert_eq!(r2, Done(&b""[..], B{a: 1, b: Some(1)})); // the second "abcd" tag is optional let r3 = z(&b"abcdefgh"[..]); assert_eq!(r3, Done(&b""[..], B{a: 1, b: Some(1)})); // the result of ret_y is optional, as seen in the B structure let r4 = z(&b"abcdabcdwxyz"[..]); assert_eq!(r4, Done(&b"wxyz"[..], B{a: 1, b: None}));