Macro nom::chain [] [src]

macro_rules! chain {
    ($i:expr, $($rest:tt)*) => { ... };
}
Deprecated since 2.0.0

: please use do_parse! instead

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

this parser is deprecated and will be removed in nom 3.0. You can now replace it with do_parse!. The ? syntax to make a parser optional can be done with the opt! combinator.

There are also combinators available for specific patterns like pair!, tuple!, preceded!, terminated!, delimited!, etc.

In lots of cases, there are better solutions than using chain!.

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