|  | /// Try a list of parsers and return the result of the first successful one | 
|  | /// | 
|  | /// ```rust,ignore | 
|  | /// alt!(I -> IResult<I,O> | I -> IResult<I,O> | ... | I -> IResult<I,O> ) => I -> IResult<I, O> | 
|  | /// ``` | 
|  | /// All the parsers must have the same return type. | 
|  | /// | 
|  | /// If one of the parsers returns `Incomplete`, `alt!` will return `Incomplete`, to retry | 
|  | /// once you get more input. Note that it is better for performance to know the | 
|  | /// minimum size of data you need before you get into `alt!`. | 
|  | /// | 
|  | /// The `alt!` combinator is used in the following way: | 
|  | /// | 
|  | /// ```rust,ignore | 
|  | /// alt!(parser_1 | parser_2 | ... | parser_n) | 
|  | /// ``` | 
|  | /// | 
|  | /// # Basic example | 
|  | /// | 
|  | /// ``` | 
|  | /// # #[macro_use] extern crate nom; | 
|  | /// # fn main() { | 
|  | ///  // Create a parser that will match either "dragon" or "beast" | 
|  | ///  named!( dragon_or_beast, alt!( tag!( "dragon" ) | tag!( "beast" ) ) ); | 
|  | /// | 
|  | ///  // Given the input "dragon slayer", the parser will match "dragon" | 
|  | ///  // and the rest will be " slayer" | 
|  | ///  let (rest, result) = dragon_or_beast(b"dragon slayer").unwrap(); | 
|  | ///  assert_eq!(result, b"dragon"); | 
|  | ///  assert_eq!(rest, b" slayer"); | 
|  | /// | 
|  | ///  // Given the input "beast of Gevaudan", the parser will match "beast" | 
|  | ///  // and the rest will be " of Gevaudan" | 
|  | ///  let (rest, result) = dragon_or_beast(&b"beast of Gevaudan"[..]).unwrap(); | 
|  | ///  assert_eq!(result, b"beast"); | 
|  | ///  assert_eq!(rest, b" of Gevaudan"); | 
|  | ///  # } | 
|  | /// ``` | 
|  | /// | 
|  | /// # Manipulate results | 
|  | /// | 
|  | /// There exists another syntax for `alt!` that gives you the ability to | 
|  | /// manipulate the result from each parser: | 
|  | /// | 
|  | /// ``` | 
|  | /// # #[macro_use] extern crate nom; | 
|  | /// # fn main() { | 
|  | /// # | 
|  | /// // We create an enum to represent our creatures | 
|  | /// #[derive(Debug,PartialEq,Eq)] | 
|  | /// enum Creature { | 
|  | ///     Dragon, | 
|  | ///     Beast, | 
|  | ///     Unknown(usize) | 
|  | /// } | 
|  | /// | 
|  | /// // Let's make a helper function that returns true when not a space | 
|  | /// // we are required to do this because the `take_while!` macro is limited | 
|  | /// // to idents, so we can't negate `ìs_space` at the call site | 
|  | /// fn is_not_space(c: u8) -> bool { ! nom::character::is_space(c) } | 
|  | /// | 
|  | /// // Our parser will return the `Dragon` variant when matching "dragon", | 
|  | /// // the `Beast` variant when matching "beast" and otherwise it will consume | 
|  | /// // the input until a space is found and return an `Unknown` creature with | 
|  | /// // the size of it's name. | 
|  | /// named!(creature<Creature>, alt!( | 
|  | ///     tag!("dragon")            => { |_| Creature::Dragon } | | 
|  | ///     tag!("beast")             => { |_| Creature::Beast }  | | 
|  | ///     take_while!(is_not_space) => { |r: &[u8]| Creature::Unknown(r.len()) } | 
|  | ///     // the closure takes the result as argument if the parser is successful | 
|  | /// )); | 
|  | /// | 
|  | /// // Given the input "dragon slayer" the parser will return `Creature::Dragon` | 
|  | /// // and the rest will be " slayer" | 
|  | /// let (rest, result) = creature(b"dragon slayer").unwrap(); | 
|  | /// assert_eq!(result, Creature::Dragon); | 
|  | /// assert_eq!(rest, b" slayer"); | 
|  | /// | 
|  | /// // Given the input "beast of Gevaudan" the parser will return `Creature::Beast` | 
|  | /// // and the rest will be " of Gevaudan" | 
|  | /// let (rest, result) = creature(b"beast of Gevaudan").unwrap(); | 
|  | /// assert_eq!(result, Creature::Beast); | 
|  | /// assert_eq!(rest, b" of Gevaudan"); | 
|  | /// | 
|  | /// // Given the input "demon hunter" the parser will return `Creature::Unkown(5)` | 
|  | /// // and the rest will be " hunter" | 
|  | /// let (rest, result) = creature(b"demon hunter").unwrap(); | 
|  | /// assert_eq!(result, Creature::Unknown(5)); | 
|  | /// assert_eq!(rest, b" hunter"); | 
|  | /// # } | 
|  | /// ``` | 
|  | /// | 
|  | /// # Behaviour of `alt!` | 
|  | /// | 
|  | /// **BE CAREFUL** there is a case where the behaviour of `alt!` can be confusing: | 
|  | /// | 
|  | /// when the alternatives have different lengths, like this case: | 
|  | /// | 
|  | /// ```ignore | 
|  | ///  named!( test, alt!( tag!( "abcd" ) | tag!( "ef" ) | tag!( "ghi" ) | tag!( "kl" ) ) ); | 
|  | /// ``` | 
|  | /// | 
|  | /// With this parser, if you pass `"abcd"` as input, the first alternative parses it correctly, | 
|  | /// but if you pass `"efg"`, the first alternative will return `Incomplete`, since it needs an input | 
|  | /// of 4 bytes. This behaviour of `alt!` is expected: if you get a partial input that isn't matched | 
|  | /// by the first alternative, but would match if the input was complete, you want `alt!` to indicate | 
|  | /// that it cannot decide with limited information. | 
|  | /// | 
|  | /// There are two ways to fix this behaviour. The first one consists in ordering the alternatives | 
|  | /// by size, like this: | 
|  | /// | 
|  | /// ```ignore | 
|  | ///  named!( test, alt!( tag!( "ef" ) | tag!( "kl") | tag!( "ghi" ) | tag!( "abcd" ) ) ); | 
|  | /// ``` | 
|  | /// | 
|  | /// With this solution, the largest alternative will be tested last. | 
|  | /// | 
|  | /// The other solution uses the `complete!` combinator, which transforms an `Incomplete` in an | 
|  | /// `Error`. If one of the alternatives returns `Incomplete` but is wrapped by `complete!`, | 
|  | /// `alt!` will try the next alternative. This is useful when you know that | 
|  | /// you will not get partial input: | 
|  | /// | 
|  | /// ```ignore | 
|  | ///  named!( test, | 
|  | ///    alt!( | 
|  | ///      complete!( tag!( "abcd" ) ) | | 
|  | ///      complete!( tag!( "ef"   ) ) | | 
|  | ///      complete!( tag!( "ghi"  ) ) | | 
|  | ///      complete!( tag!( "kl"   ) ) | 
|  | ///    ) | 
|  | ///  ); | 
|  | /// ``` | 
|  | /// | 
|  | /// This behaviour of `alt!` can get especially confusing if multiple alternatives have different | 
|  | /// sizes but a common prefix, like this: | 
|  | /// | 
|  | /// ```ignore | 
|  | ///  named!( test, alt!( tag!( "abcd" ) | tag!( "ab" ) | tag!( "ef" ) ) ); | 
|  | /// ``` | 
|  | /// | 
|  | /// in that case, if you order by size, passing `"abcd"` as input will always be matched by the | 
|  | /// smallest parser, so the solution using `complete!` is better suited. | 
|  | /// | 
|  | /// You can also nest multiple `alt!`, like this: | 
|  | /// | 
|  | /// ```ignore | 
|  | ///  named!( test, | 
|  | ///    alt!( | 
|  | ///      preceded!( | 
|  | ///        tag!("ab"), | 
|  | ///        alt!( | 
|  | ///          tag!( "cd" ) | | 
|  | ///          eof!() | 
|  | ///        ) | 
|  | ///      ) | 
|  | ///    | tag!( "ef" ) | 
|  | ///    ) | 
|  | ///  ); | 
|  | /// ``` | 
|  | /// | 
|  | ///  `preceded!` will first parse `"ab"` then, if successful, try the alternatives "cd", | 
|  | ///  or empty input (End Of File). If none of them work, `preceded!` will fail and | 
|  | ///  "ef" will be tested. | 
|  | /// | 
|  | #[macro_export(local_inner_macros)] | 
|  | macro_rules! alt ( | 
|  | (__impl $i:expr, $submac:ident!( $($args:tt)* ), $($rest:tt)* ) => ( | 
|  | nom_compile_error!("alt uses '|' as separator, not ',': | 
|  |  | 
|  | alt!( | 
|  | tag!(\"abcd\") | | 
|  | tag!(\"efgh\") | | 
|  | tag!(\"ijkl\") | 
|  | ) | 
|  | "); | 
|  | ); | 
|  | (__impl $i:expr, $e:path, $($rest:tt)* ) => ( | 
|  | alt!(__impl $i, call!($e) , $($rest)*); | 
|  | ); | 
|  | (__impl $i:expr, $e:path | $($rest:tt)*) => ( | 
|  | alt!(__impl $i, call!($e) | $($rest)*); | 
|  | ); | 
|  |  | 
|  | (__impl $i:expr, $subrule:ident!( $($args:tt)*) | $($rest:tt)*) => ( | 
|  | { | 
|  | use $crate::lib::std::result::Result::*; | 
|  | use $crate::Err; | 
|  |  | 
|  | let i_ = $i.clone(); | 
|  | let res = $subrule!(i_, $($args)*); | 
|  | match res { | 
|  | Ok(o) => Ok(o), | 
|  | Err(Err::Error(e))      => { | 
|  | let out = alt!(__impl $i, $($rest)*); | 
|  |  | 
|  | // Compile-time hack to ensure that res's E type is not under-specified. | 
|  | // This all has no effect at runtime. | 
|  | #[allow(dead_code)] | 
|  | fn unify_types<T>(_: &T, _: &T) {} | 
|  | if let Err(Err::Error(ref e2)) = out { | 
|  | unify_types(&e, e2); | 
|  | } | 
|  |  | 
|  | out | 
|  | }, | 
|  | Err(e) => Err(e), | 
|  | } | 
|  | } | 
|  | ); | 
|  |  | 
|  | (__impl $i:expr, $subrule:ident!( $($args:tt)* ) => { $gen:expr } | $($rest:tt)*) => ( | 
|  | { | 
|  | use $crate::lib::std::result::Result::*; | 
|  | use $crate::Err; | 
|  |  | 
|  | let i_ = $i.clone(); | 
|  | match $subrule!(i_, $($args)* ) { | 
|  | Ok((i,o))         => Ok((i,$gen(o))), | 
|  | Err(Err::Error(e)) => { | 
|  | let out = alt!(__impl $i, $($rest)*); | 
|  |  | 
|  | // Compile-time hack to ensure that res's E type is not under-specified. | 
|  | // This all has no effect at runtime. | 
|  | fn unify_types<T>(_: &T, _: &T) {} | 
|  | if let Err(Err::Error(ref e2)) = out { | 
|  | unify_types(&e, e2); | 
|  | } | 
|  |  | 
|  | out | 
|  | }, | 
|  | Err(e) => Err(e), | 
|  | } | 
|  | } | 
|  | ); | 
|  |  | 
|  | (__impl $i:expr, $e:path => { $gen:expr } | $($rest:tt)*) => ( | 
|  | alt!(__impl $i, call!($e) => { $gen } | $($rest)*); | 
|  | ); | 
|  |  | 
|  | (__impl $i:expr, __end) => ( | 
|  | { | 
|  | use $crate::{Err,error::ErrorKind}; | 
|  | let e2 = ErrorKind::Alt; | 
|  | let err = Err::Error(error_position!($i, e2)); | 
|  |  | 
|  | Err(err) | 
|  | } | 
|  | ); | 
|  |  | 
|  | ($i:expr, $($rest:tt)*) => ( | 
|  | { | 
|  | alt!(__impl $i, $($rest)* | __end) | 
|  | } | 
|  | ); | 
|  | ); | 
|  |  | 
|  | /// `switch!(I -> IResult<I,P>, P => I -> IResult<I,O> | ... | P => I -> IResult<I,O> ) => I -> IResult<I, O>` | 
|  | /// choose the next parser depending on the result of the first one, if successful, | 
|  | /// and returns the result of the second parser | 
|  | /// | 
|  | /// ``` | 
|  | /// # #[macro_use] extern crate nom; | 
|  | /// # use nom::Err; | 
|  | /// # use nom::error::ErrorKind; | 
|  | /// # fn main() { | 
|  | ///  named!(sw, | 
|  | ///    switch!(take!(4), | 
|  | ///      b"abcd" => tag!("XYZ") | | 
|  | ///      b"efgh" => tag!("123") | 
|  | ///    ) | 
|  | ///  ); | 
|  | /// | 
|  | ///  let a = b"abcdXYZ123"; | 
|  | ///  let b = b"abcdef"; | 
|  | ///  let c = b"efgh123"; | 
|  | ///  let d = b"blah"; | 
|  | /// | 
|  | ///  assert_eq!(sw(&a[..]), Ok((&b"123"[..], &b"XYZ"[..]))); | 
|  | ///  assert_eq!(sw(&b[..]), Err(Err::Error(error_node_position!(&b"abcdef"[..], ErrorKind::Switch, | 
|  | ///    error_position!(&b"ef"[..], ErrorKind::Tag))))); | 
|  | ///  assert_eq!(sw(&c[..]), Ok((&b""[..], &b"123"[..]))); | 
|  | ///  assert_eq!(sw(&d[..]), Err(Err::Error(error_position!(&b"blah"[..], ErrorKind::Switch)))); | 
|  | ///  # } | 
|  | /// ``` | 
|  | /// | 
|  | /// You can specify a default case like with a normal match, using `_` | 
|  | /// | 
|  | /// ``` | 
|  | /// # #[macro_use] extern crate nom; | 
|  | /// # fn main() { | 
|  | ///  named!(sw, | 
|  | ///    switch!(take!(4), | 
|  | ///      b"abcd" => tag!("XYZ") | | 
|  | ///      _       => value!(&b"default"[..]) | 
|  | ///    ) | 
|  | ///  ); | 
|  | /// | 
|  | ///  let a = b"abcdXYZ123"; | 
|  | ///  let b = b"blah"; | 
|  | /// | 
|  | ///  assert_eq!(sw(&a[..]), Ok((&b"123"[..], &b"XYZ"[..]))); | 
|  | ///  assert_eq!(sw(&b[..]), Ok((&b""[..], &b"default"[..]))); | 
|  | ///  # } | 
|  | /// ``` | 
|  | /// | 
|  | /// Due to limitations in Rust macros, it is not possible to have simple functions on the right hand | 
|  | /// side of pattern, like this: | 
|  | /// | 
|  | /// ```ignore | 
|  | ///  named!(xyz, tag!("XYZ")); | 
|  | ///  named!(num, tag!("123")); | 
|  | ///  named!(sw, | 
|  | ///    switch!(take!(4), | 
|  | ///      b"abcd" => xyz | | 
|  | ///      b"efgh" => 123 | 
|  | ///    ) | 
|  | ///  ); | 
|  | /// ``` | 
|  | /// | 
|  | /// If you want to pass your own functions instead, you can use the `call!` combinator as follows: | 
|  | /// | 
|  | /// ```ignore | 
|  | ///  named!(xyz, tag!("XYZ")); | 
|  | ///  named!(num, tag!("123")); | 
|  | ///  named!(sw, | 
|  | ///    switch!(take!(4), | 
|  | ///      b"abcd" => call!(xyz) | | 
|  | ///      b"efgh" => call!(num) | 
|  | ///    ) | 
|  | ///  ); | 
|  | /// ``` | 
|  | /// | 
|  | #[macro_export(local_inner_macros)] | 
|  | macro_rules! switch ( | 
|  | (__impl $i:expr, $submac:ident!( $($args:tt)* ), $( $($p:pat)|+ => $subrule:ident!( $($args2:tt)* ))|* ) => ( | 
|  | { | 
|  | use $crate::lib::std::result::Result::*; | 
|  | use $crate::lib::std::option::Option::*; | 
|  | use $crate::{Err,error::ErrorKind}; | 
|  |  | 
|  | let i_ = $i.clone(); | 
|  | match map!(i_, $submac!($($args)*), Some) { | 
|  | Err(Err::Error(err))      => { | 
|  | fn unify_types<T>(_: &T, _: &T) {} | 
|  | let e1 = ErrorKind::Switch; | 
|  | let e2 = error_position!($i, e1.clone()); | 
|  | unify_types(&err, &e2); | 
|  |  | 
|  | Err(Err::Error(error_node_position!($i, e1, err))) | 
|  | }, | 
|  | Err(e) => Err(e), | 
|  | Ok((i, o))    => { | 
|  |  | 
|  | match o { | 
|  | $($(Some($p) )|+ => match $subrule!(i, $($args2)*) { | 
|  | Err(Err::Error(err)) => { | 
|  | fn unify_types<T>(_: &T, _: &T) {} | 
|  | let e1 = ErrorKind::Switch; | 
|  | let e2 = error_position!($i, e1.clone()); | 
|  | unify_types(&err, &e2); | 
|  |  | 
|  | Err(Err::Error(error_node_position!($i, e1, err))) | 
|  | }, | 
|  | Ok(o) => Ok(o), | 
|  | Err(e) => Err(e), | 
|  | }),*, | 
|  | _    => Err(Err::convert(Err::Error(error_position!($i, ErrorKind::Switch)))) | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | ); | 
|  | ($i:expr, $submac:ident!( $($args:tt)*), $($rest:tt)*) => ( | 
|  | { | 
|  | switch!(__impl $i, $submac!($($args)*), $($rest)*) | 
|  | } | 
|  | ); | 
|  | ($i:expr, $e:path, $($rest:tt)*) => ( | 
|  | { | 
|  | switch!(__impl $i, call!($e), $($rest)*) | 
|  | } | 
|  | ); | 
|  | ); | 
|  |  | 
|  | /// | 
|  | /// | 
|  | /// `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 | 
|  | /// | 
|  | /// ``` | 
|  | /// # #[macro_use] extern crate nom; | 
|  | /// # use nom::{Err,error::ErrorKind,Needed}; | 
|  | /// # fn main() { | 
|  | /// 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: | 
|  | /// | 
|  | /// ``` | 
|  | /// # #[macro_use] extern crate nom; | 
|  | /// # use nom::{Err,error::ErrorKind,Needed}; | 
|  | /// # fn main() { | 
|  | /// 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)))); | 
|  | /// # } | 
|  | /// ``` | 
|  | #[macro_export(local_inner_macros)] | 
|  | macro_rules! permutation ( | 
|  | ($i:expr, $($rest:tt)*) => ( | 
|  | { | 
|  | use $crate::lib::std::result::Result::*; | 
|  | use $crate::lib::std::option::Option::*; | 
|  | use $crate::{Err,error::ErrorKind}; | 
|  |  | 
|  | let mut res    = permutation_init!((), $($rest)*); | 
|  | let mut input  = $i; | 
|  | let mut error  = None; | 
|  | let mut needed = None; | 
|  |  | 
|  | loop { | 
|  | let mut all_done = true; | 
|  | permutation_iterator!(0, input, all_done, needed, res, $($rest)*); | 
|  |  | 
|  | //if we reach that part, it means none of the parsers were able to read anything | 
|  | if !all_done { | 
|  | //FIXME: should wrap the error returned by the child parser | 
|  | error = Some(error_position!(input, ErrorKind::Permutation)); | 
|  | } | 
|  | break; | 
|  | } | 
|  |  | 
|  | if let Some(need) = needed { | 
|  | Err(Err::convert(need)) | 
|  | } else { | 
|  | if let Some(unwrapped_res) = { permutation_unwrap!(0, (), res, $($rest)*) } { | 
|  | Ok((input, unwrapped_res)) | 
|  | } else { | 
|  | if let Some(e) = error { | 
|  | Err(Err::Error(error_node_position!($i, ErrorKind::Permutation, e))) | 
|  | } else { | 
|  | Err(Err::Error(error_position!($i, ErrorKind::Permutation))) | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | ); | 
|  | ); | 
|  |  | 
|  | #[doc(hidden)] | 
|  | #[macro_export(local_inner_macros)] | 
|  | macro_rules! permutation_init ( | 
|  | ((), $e:ident?, $($rest:tt)*) => ( | 
|  | permutation_init!(($crate::lib::std::option::Option::None), $($rest)*) | 
|  | ); | 
|  | ((), $e:ident, $($rest:tt)*) => ( | 
|  | permutation_init!(($crate::lib::std::option::Option::None), $($rest)*) | 
|  | ); | 
|  |  | 
|  | ((), $submac:ident!( $($args:tt)* )?, $($rest:tt)*) => ( | 
|  | permutation_init!(($crate::lib::std::option::Option::None), $($rest)*) | 
|  | ); | 
|  | ((), $submac:ident!( $($args:tt)* ), $($rest:tt)*) => ( | 
|  | permutation_init!(($crate::lib::std::option::Option::None), $($rest)*) | 
|  | ); | 
|  |  | 
|  | (($($parsed:expr),*), $e:ident?, $($rest:tt)*) => ( | 
|  | permutation_init!(($($parsed),* , $crate::lib::std::option::Option::None), $($rest)*); | 
|  | ); | 
|  | (($($parsed:expr),*), $e:ident, $($rest:tt)*) => ( | 
|  | permutation_init!(($($parsed),* , $crate::lib::std::option::Option::None), $($rest)*); | 
|  | ); | 
|  |  | 
|  | (($($parsed:expr),*), $submac:ident!( $($args:tt)* )?, $($rest:tt)*) => ( | 
|  | permutation_init!(($($parsed),* , $crate::lib::std::option::Option::None), $($rest)*); | 
|  | ); | 
|  | (($($parsed:expr),*), $submac:ident!( $($args:tt)* ), $($rest:tt)*) => ( | 
|  | permutation_init!(($($parsed),* , $crate::lib::std::option::Option::None), $($rest)*); | 
|  | ); | 
|  |  | 
|  | (($($parsed:expr),*), $e:ident) => ( | 
|  | ($($parsed),* , $crate::lib::std::option::Option::None) | 
|  | ); | 
|  | (($($parsed:expr),*), $e:ident?) => ( | 
|  | ($($parsed),* , $crate::lib::std::option::Option::None) | 
|  | ); | 
|  |  | 
|  | (($($parsed:expr),*), $submac:ident!( $($args:tt)* )?) => ( | 
|  | ($($parsed),* , $crate::lib::std::option::Option::None) | 
|  | ); | 
|  | (($($parsed:expr),*), $submac:ident!( $($args:tt)* )) => ( | 
|  | ($($parsed),* , $crate::lib::std::option::Option::None) | 
|  | ); | 
|  | (($($parsed:expr),*),) => ( | 
|  | ($($parsed),*) | 
|  | ); | 
|  | ); | 
|  |  | 
|  | #[doc(hidden)] | 
|  | #[macro_export(local_inner_macros)] | 
|  | macro_rules! succ ( | 
|  | (0, $submac:ident ! ($($rest:tt)*)) => ($submac!(1, $($rest)*)); | 
|  | (1, $submac:ident ! ($($rest:tt)*)) => ($submac!(2, $($rest)*)); | 
|  | (2, $submac:ident ! ($($rest:tt)*)) => ($submac!(3, $($rest)*)); | 
|  | (3, $submac:ident ! ($($rest:tt)*)) => ($submac!(4, $($rest)*)); | 
|  | (4, $submac:ident ! ($($rest:tt)*)) => ($submac!(5, $($rest)*)); | 
|  | (5, $submac:ident ! ($($rest:tt)*)) => ($submac!(6, $($rest)*)); | 
|  | (6, $submac:ident ! ($($rest:tt)*)) => ($submac!(7, $($rest)*)); | 
|  | (7, $submac:ident ! ($($rest:tt)*)) => ($submac!(8, $($rest)*)); | 
|  | (8, $submac:ident ! ($($rest:tt)*)) => ($submac!(9, $($rest)*)); | 
|  | (9, $submac:ident ! ($($rest:tt)*)) => ($submac!(10, $($rest)*)); | 
|  | (10, $submac:ident ! ($($rest:tt)*)) => ($submac!(11, $($rest)*)); | 
|  | (11, $submac:ident ! ($($rest:tt)*)) => ($submac!(12, $($rest)*)); | 
|  | (12, $submac:ident ! ($($rest:tt)*)) => ($submac!(13, $($rest)*)); | 
|  | (13, $submac:ident ! ($($rest:tt)*)) => ($submac!(14, $($rest)*)); | 
|  | (14, $submac:ident ! ($($rest:tt)*)) => ($submac!(15, $($rest)*)); | 
|  | (15, $submac:ident ! ($($rest:tt)*)) => ($submac!(16, $($rest)*)); | 
|  | (16, $submac:ident ! ($($rest:tt)*)) => ($submac!(17, $($rest)*)); | 
|  | (17, $submac:ident ! ($($rest:tt)*)) => ($submac!(18, $($rest)*)); | 
|  | (18, $submac:ident ! ($($rest:tt)*)) => ($submac!(19, $($rest)*)); | 
|  | (19, $submac:ident ! ($($rest:tt)*)) => ($submac!(20, $($rest)*)); | 
|  | ); | 
|  |  | 
|  | #[doc(hidden)] | 
|  | #[macro_export(local_inner_macros)] | 
|  | macro_rules! permutation_unwrap ( | 
|  | ($it:tt,  (), $res:ident, $e:ident?, $($rest:tt)*) => ( | 
|  | succ!($it, permutation_unwrap!(($res.$it), $res, $($rest)*)); | 
|  | ); | 
|  | ($it:tt,  (), $res:ident, $e:ident, $($rest:tt)*) => ({ | 
|  | let res = $res.$it; | 
|  | if res.is_some() { | 
|  | succ!($it, permutation_unwrap!((res.unwrap()), $res, $($rest)*)) | 
|  | } else { | 
|  | $crate::lib::std::option::Option::None | 
|  | } | 
|  | }); | 
|  |  | 
|  | ($it:tt,  (), $res:ident, $submac:ident!( $($args:tt)* )?, $($rest:tt)*) => ( | 
|  | succ!($it, permutation_unwrap!(($res.$it), $res, $($rest)*)); | 
|  | ); | 
|  | ($it:tt,  (), $res:ident, $submac:ident!( $($args:tt)* ), $($rest:tt)*) => ({ | 
|  | let res = $res.$it; | 
|  | if res.is_some() { | 
|  | succ!($it, permutation_unwrap!((res.unwrap()), $res, $($rest)*)) | 
|  | } else { | 
|  | $crate::lib::std::option::Option::None | 
|  | } | 
|  | }); | 
|  |  | 
|  | ($it:tt, ($($parsed:expr),*), $res:ident, $e:ident?, $($rest:tt)*) => ( | 
|  | succ!($it, permutation_unwrap!(($($parsed),* , $res.$it), $res, $($rest)*)); | 
|  | ); | 
|  | ($it:tt, ($($parsed:expr),*), $res:ident, $e:ident, $($rest:tt)*) => ({ | 
|  | let res = $res.$it; | 
|  | if res.is_some() { | 
|  | succ!($it, permutation_unwrap!(($($parsed),* , res.unwrap()), $res, $($rest)*)) | 
|  | } else { | 
|  | $crate::lib::std::option::Option::None | 
|  | } | 
|  | }); | 
|  |  | 
|  | ($it:tt, ($($parsed:expr),*), $res:ident, $submac:ident!( $($args:tt)* )?, $($rest:tt)*) => ( | 
|  | succ!($it, permutation_unwrap!(($($parsed),* , $res.$it), $res, $($rest)*)); | 
|  | ); | 
|  | ($it:tt, ($($parsed:expr),*), $res:ident, $submac:ident!( $($args:tt)* ), $($rest:tt)*) => ({ | 
|  | let res = $res.$it; | 
|  | if res.is_some() { | 
|  | succ!($it, permutation_unwrap!(($($parsed),* , res.unwrap()), $res, $($rest)*)) | 
|  | } else { | 
|  | $crate::lib::std::option::Option::None | 
|  | } | 
|  | }); | 
|  |  | 
|  | ($it:tt, ($($parsed:expr),*), $res:ident?, $e:ident) => ( | 
|  | $crate::lib::std::option::Option::Some(($($parsed),* , { $res.$it })) | 
|  | ); | 
|  | ($it:tt, ($($parsed:expr),*), $res:ident, $e:ident) => ({ | 
|  | let res = $res.$it; | 
|  | if res.is_some() { | 
|  | $crate::lib::std::option::Option::Some(($($parsed),* , res.unwrap() )) | 
|  | } else { | 
|  | $crate::lib::std::option::Option::None | 
|  | } | 
|  | }); | 
|  |  | 
|  | ($it:tt, ($($parsed:expr),*), $res:ident, $submac:ident!( $($args:tt)* )?) => ( | 
|  | $crate::lib::std::option::Option::Some(($($parsed),* , { $res.$it })) | 
|  | ); | 
|  | ($it:tt, ($($parsed:expr),*), $res:ident, $submac:ident!( $($args:tt)* )) => ({ | 
|  | let res = $res.$it; | 
|  | if res.is_some() { | 
|  | $crate::lib::std::option::Option::Some(($($parsed),* , res.unwrap() )) | 
|  | } else { | 
|  | $crate::lib::std::option::Option::None | 
|  | } | 
|  | }); | 
|  | ); | 
|  |  | 
|  | #[doc(hidden)] | 
|  | #[macro_export(local_inner_macros)] | 
|  | macro_rules! permutation_iterator ( | 
|  | ($it:tt,$i:expr, $all_done:expr, $needed:expr, $res:expr, $e:ident?, $($rest:tt)*) => ( | 
|  | permutation_iterator!($it, $i, $all_done, $needed, $res, call!($e), $($rest)*); | 
|  | ); | 
|  | ($it:tt,$i:expr, $all_done:expr, $needed:expr, $res:expr, $e:ident, $($rest:tt)*) => ( | 
|  | permutation_iterator!($it, $i, $all_done, $needed, $res, call!($e), $($rest)*); | 
|  | ); | 
|  |  | 
|  | ($it:tt, $i:expr, $all_done:expr, $needed:expr, $res:expr, $submac:ident!( $($args:tt)* )?, $($rest:tt)*) => { | 
|  | permutation_iterator!($it, $i, $all_done, $needed, $res, $submac!($($args)*) , $($rest)*); | 
|  | }; | 
|  | ($it:tt, $i:expr, $all_done:expr, $needed:expr, $res:expr, $submac:ident!( $($args:tt)* ), $($rest:tt)*) => ({ | 
|  | use $crate::lib::std::result::Result::*; | 
|  | use $crate::lib::std::option::Option::*; | 
|  | use $crate::Err; | 
|  |  | 
|  | if $res.$it.is_none() { | 
|  | match $submac!($i, $($args)*) { | 
|  | Ok((i,o))     => { | 
|  | $i = i; | 
|  | $res.$it = Some(o); | 
|  | continue; | 
|  | }, | 
|  | Err(Err::Error(_)) => { | 
|  | $all_done = false; | 
|  | }, | 
|  | Err(e) => { | 
|  | $needed = Some(e); | 
|  | break; | 
|  | } | 
|  | }; | 
|  | } | 
|  | succ!($it, permutation_iterator!($i, $all_done, $needed, $res, $($rest)*)); | 
|  | }); | 
|  |  | 
|  | ($it:tt,$i:expr, $all_done:expr, $needed:expr, $res:expr, $e:ident?) => ( | 
|  | permutation_iterator!($it, $i, $all_done, $needed, $res, call!($e)); | 
|  | ); | 
|  | ($it:tt,$i:expr, $all_done:expr, $needed:expr, $res:expr, $e:ident) => ( | 
|  | permutation_iterator!($it, $i, $all_done, $needed, $res, call!($e)); | 
|  | ); | 
|  |  | 
|  | ($it:tt, $i:expr, $all_done:expr, $needed:expr, $res:expr, $submac:ident!( $($args:tt)* )?) => { | 
|  | permutation_iterator!($it, $i, $all_done, $needed, $res, $submac!($($args)*)); | 
|  | }; | 
|  | ($it:tt, $i:expr, $all_done:expr, $needed:expr, $res:expr, $submac:ident!( $($args:tt)* )) => ({ | 
|  | use $crate::lib::std::result::Result::*; | 
|  | use $crate::lib::std::option::Option::*; | 
|  | use $crate::Err; | 
|  |  | 
|  | if $res.$it.is_none() { | 
|  | match $submac!($i, $($args)*) { | 
|  | Ok((i,o))     => { | 
|  | $i = i; | 
|  | $res.$it = Some(o); | 
|  | continue; | 
|  | }, | 
|  | Err(Err::Error(_)) => { | 
|  | $all_done = false; | 
|  | }, | 
|  | Err(e) => { | 
|  | $needed = Some(e); | 
|  | break; | 
|  | } | 
|  | }; | 
|  | } | 
|  | }); | 
|  | ); | 
|  |  | 
|  | #[cfg(test)] | 
|  | mod tests { | 
|  | use crate::error::ErrorKind; | 
|  | #[cfg(feature = "alloc")] | 
|  | use crate::{ | 
|  | error::ParseError, | 
|  | lib::std::{ | 
|  | fmt::Debug, | 
|  | string::{String, ToString} | 
|  | } | 
|  | }; | 
|  | use crate::internal::{Err, IResult, Needed}; | 
|  |  | 
|  | // reproduce the tag and take macros, because of module import order | 
|  | macro_rules! tag ( | 
|  | ($i:expr, $inp: expr) => ( | 
|  | { | 
|  | #[inline(always)] | 
|  | fn as_bytes<T: $crate::AsBytes>(b: &T) -> &[u8] { | 
|  | b.as_bytes() | 
|  | } | 
|  |  | 
|  | let expected = $inp; | 
|  | let bytes    = as_bytes(&expected); | 
|  |  | 
|  | tag_bytes!($i,bytes) | 
|  | } | 
|  | ); | 
|  | ); | 
|  |  | 
|  | macro_rules! tag_bytes ( | 
|  | ($i:expr, $bytes: expr) => ( | 
|  | { | 
|  | use $crate::lib::std::cmp::min; | 
|  |  | 
|  | let len = $i.len(); | 
|  | let blen = $bytes.len(); | 
|  | let m   = min(len, blen); | 
|  | let reduced = &$i[..m]; | 
|  | let b       = &$bytes[..m]; | 
|  |  | 
|  | let res: IResult<_,_,_> = if reduced != b { | 
|  | let e: ErrorKind = ErrorKind::Tag; | 
|  | Err(Err::Error(error_position!($i, e))) | 
|  | } else if m < blen { | 
|  | Err(Err::Incomplete(Needed::Size(blen))) | 
|  | } else { | 
|  | Ok((&$i[blen..], reduced)) | 
|  | }; | 
|  | res | 
|  | } | 
|  | ); | 
|  | ); | 
|  |  | 
|  | macro_rules! take( | 
|  | ($i:expr, $count:expr) => ( | 
|  | { | 
|  | let cnt = $count as usize; | 
|  | let res:IResult<&[u8],&[u8],_> = if $i.len() < cnt { | 
|  | Err(Err::Incomplete(Needed::Size(cnt))) | 
|  | } else { | 
|  | Ok((&$i[cnt..],&$i[0..cnt])) | 
|  | }; | 
|  | res | 
|  | } | 
|  | ); | 
|  | ); | 
|  |  | 
|  | #[cfg(feature = "alloc")] | 
|  | #[derive(Debug, Clone, PartialEq)] | 
|  | pub struct ErrorStr(String); | 
|  |  | 
|  | #[cfg(feature = "alloc")] | 
|  | impl From<u32> for ErrorStr { | 
|  | fn from(i: u32) -> Self { | 
|  | ErrorStr(format!("custom error code: {}", i)) | 
|  | } | 
|  | } | 
|  |  | 
|  | #[cfg(feature = "alloc")] | 
|  | impl<'a> From<&'a str> for ErrorStr { | 
|  | fn from(i: &'a str) -> Self { | 
|  | ErrorStr(format!("custom error message: {}", i)) | 
|  | } | 
|  | } | 
|  |  | 
|  | #[cfg(feature = "alloc")] | 
|  | impl<I: Debug> ParseError<I> for ErrorStr { | 
|  | fn from_error_kind(input: I, kind: ErrorKind) -> Self { | 
|  | ErrorStr(format!("custom error message: ({:?}, {:?})", input, kind)) | 
|  | } | 
|  |  | 
|  | fn append(input: I, kind: ErrorKind, other: Self) -> Self { | 
|  | ErrorStr(format!("custom error message: ({:?}, {:?}) - {:?}", input, kind, other)) | 
|  | } | 
|  | } | 
|  |  | 
|  | #[cfg(feature = "alloc")] | 
|  | #[test] | 
|  | fn alt() { | 
|  | fn work(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { | 
|  | Ok((&b""[..], input)) | 
|  | } | 
|  |  | 
|  | #[allow(unused_variables)] | 
|  | fn dont_work(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { | 
|  | Err(Err::Error(ErrorStr("abcd".to_string()))) | 
|  | } | 
|  |  | 
|  | fn work2(input: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { | 
|  | Ok((input, &b""[..])) | 
|  | } | 
|  |  | 
|  | fn alt1(i: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { | 
|  | alt!(i, dont_work | dont_work) | 
|  | } | 
|  | fn alt2(i: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { | 
|  | alt!(i, dont_work | work) | 
|  | } | 
|  | fn alt3(i: &[u8]) -> IResult<&[u8], &[u8], ErrorStr> { | 
|  | alt!(i, dont_work | dont_work | work2 | dont_work) | 
|  | } | 
|  | //named!(alt1, alt!(dont_work | dont_work)); | 
|  | //named!(alt2, alt!(dont_work | work)); | 
|  | //named!(alt3, alt!(dont_work | dont_work | work2 | dont_work)); | 
|  |  | 
|  | let a = &b"abcd"[..]; | 
|  | assert_eq!(alt1(a), Err(Err::Error(error_position!(a, ErrorKind::Alt)))); | 
|  | assert_eq!(alt2(a), Ok((&b""[..], a))); | 
|  | assert_eq!(alt3(a), Ok((a, &b""[..]))); | 
|  |  | 
|  | named!(alt4, alt!(tag!("abcd") | tag!("efgh"))); | 
|  | let b = &b"efgh"[..]; | 
|  | assert_eq!(alt4(a), Ok((&b""[..], a))); | 
|  | assert_eq!(alt4(b), Ok((&b""[..], b))); | 
|  |  | 
|  | // test the alternative syntax | 
|  | named!(alt5<bool>, alt!(tag!("abcd") => { |_| false } | tag!("efgh") => { |_| true })); | 
|  | assert_eq!(alt5(a), Ok((&b""[..], false))); | 
|  | assert_eq!(alt5(b), Ok((&b""[..], true))); | 
|  |  | 
|  | // compile-time test guarding against an underspecified E generic type (#474) | 
|  | named!(alt_eof1, alt!(eof!() | eof!())); | 
|  | named!(alt_eof2, alt!(eof!() => {|x| x} | eof!() => {|x| x})); | 
|  | let _ = (alt_eof1, alt_eof2); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn alt_incomplete() { | 
|  | named!(alt1, alt!(tag!("a") | tag!("bc") | tag!("def"))); | 
|  |  | 
|  | let a = &b""[..]; | 
|  | assert_eq!(alt1(a), Err(Err::Incomplete(Needed::Size(1)))); | 
|  | let a = &b"b"[..]; | 
|  | assert_eq!(alt1(a), Err(Err::Incomplete(Needed::Size(2)))); | 
|  | let a = &b"bcd"[..]; | 
|  | assert_eq!(alt1(a), Ok((&b"d"[..], &b"bc"[..]))); | 
|  | let a = &b"cde"[..]; | 
|  | assert_eq!(alt1(a), Err(Err::Error(error_position!(a, ErrorKind::Alt)))); | 
|  | let a = &b"de"[..]; | 
|  | assert_eq!(alt1(a), Err(Err::Incomplete(Needed::Size(3)))); | 
|  | let a = &b"defg"[..]; | 
|  | assert_eq!(alt1(a), Ok((&b"g"[..], &b"def"[..]))); | 
|  | } | 
|  |  | 
|  | #[allow(unused_variables)] | 
|  | #[test] | 
|  | fn switch() { | 
|  | named!( | 
|  | sw, | 
|  | switch!(take!(4), | 
|  | b"abcd" | b"xxxx" => take!(2) | | 
|  | b"efgh" => take!(4) | 
|  | ) | 
|  | ); | 
|  |  | 
|  | let a = &b"abcdefgh"[..]; | 
|  | assert_eq!(sw(a), Ok((&b"gh"[..], &b"ef"[..]))); | 
|  |  | 
|  | let b = &b"efghijkl"[..]; | 
|  | assert_eq!(sw(b), Ok((&b""[..], &b"ijkl"[..]))); | 
|  | let c = &b"afghijkl"[..]; | 
|  | assert_eq!(sw(c), Err(Err::Error(error_position!(&b"afghijkl"[..], ErrorKind::Switch)))); | 
|  |  | 
|  | let a = &b"xxxxefgh"[..]; | 
|  | assert_eq!(sw(a), Ok((&b"gh"[..], &b"ef"[..]))); | 
|  | } | 
|  |  | 
|  | #[test] | 
|  | fn permutation() { | 
|  | named!(perm<(&[u8], &[u8], &[u8])>, permutation!(tag!("abcd"), tag!("efg"), tag!("hi"))); | 
|  |  | 
|  | let expected = (&b"abcd"[..], &b"efg"[..], &b"hi"[..]); | 
|  |  | 
|  | let a = &b"abcdefghijk"[..]; | 
|  | assert_eq!(perm(a), Ok((&b"jk"[..], expected))); | 
|  | let b = &b"efgabcdhijk"[..]; | 
|  | assert_eq!(perm(b), Ok((&b"jk"[..], expected))); | 
|  | let c = &b"hiefgabcdjk"[..]; | 
|  | assert_eq!(perm(c), Ok((&b"jk"[..], 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)))); | 
|  | } | 
|  |  | 
|  | /* | 
|  | named!(does_not_compile, | 
|  | alt!(tag!("abcd"), tag!("efgh")) | 
|  | ); | 
|  | */ | 
|  | } |