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}));