//! Macro combinators
//!
//! Macros are used to make combination easier,
//! since they often do not depend on the type
//! of the data they manipulate or return.
//!
//! There is a trick to make them easier to assemble,
//! combinators are defined like this:
//!
//! ```ignore
//! macro_rules! tag (
//!   ($i:expr, $inp: expr) => (
//!     {
//!       ...
//!     }
//!   );
//! );
//! ```
//!
//! But when used in other combinators, are Used
//! like this:
//!
//! ```ignore
//! named!(my_function, tag!("abcd"));
//! ```
//!
//! Internally, other combinators will rewrite
//! that call to pass the input as first argument:
//!
//! ```ignore
//! macro_rules! named (
//!   ($name:ident, $submac:ident!( $($args:tt)* )) => (
//!     fn $name<'a>( i: &'a [u8] ) -> IResult<'a,&[u8], &[u8]> {
//!       $submac!(i, $($args)*)
//!     }
//!   );
//! );
//! ```
//!
//! If you want to call a combinator directly, you can
//! do it like this:
//!
//! ```ignore
//! let res = { tag!(input, "abcd"); }
//! ```
//!
//! Combinators must have a specific variant for
//! non-macro arguments. Example: passing a function
//! to take_while! instead of another combinator.
//!
//! ```ignore
//! macro_rules! take_while(
//!   ($input:expr, $submac:ident!( $($args:tt)* )) => (
//!     {
//!       ...
//!     }
//!   );
//!
//!   // wrap the function in a macro to pass it to the main implementation
//!   ($input:expr, $f:expr) => (
//!     take_while!($input, call!($f));
//!   );
//! );
//! ```
#[allow(unused_variables)]

/// Makes a function from a parser combination
///
/// The type can be set up if the compiler needs
/// more information
///
/// Function-like declaration:
/// ```
/// # use nom::{named, tag};
/// named!(my_function( &[u8] ) -> &[u8], tag!("abcd"));
/// ```
/// Alternative declaration. First type parameter is input, second is output:
/// ```
/// # use nom::{named, tag};
/// named!(my_function<&[u8], &[u8]>, tag!("abcd"));
/// ```
/// This one will have &[u8] as input type, &[u8] as output type:
/// ```
/// # use nom::{named, tag};
/// named!(my_function, tag!("abcd"));
/// ```
/// Will use &[u8] as output type:
/// ```
/// # use nom::{named, tag};
/// named!(my_function<&[u8]>, tag!("abcd"));
/// ```
/// Prefix them with 'pub' to make the functions public:
/// ```
/// # use nom::{named, tag};
/// named!(pub my_function, tag!("abcd"));
/// ```
/// Prefix them with 'pub(crate)' to make the functions public within the crate:
/// ```
/// # use nom::{named, tag};
/// named!(pub(crate) my_function, tag!("abcd"));
/// ```
#[macro_export(local_inner_macros)]
macro_rules! named (
    (#$($args:tt)*) => (
        named_attr!(#$($args)*);
    );
    ($vis:vis $name:ident( $i:ty ) -> $o:ty, $submac:ident!( $($args:tt)* )) => (
        $vis fn $name( i: $i ) -> $crate::IResult<$i, $o, ($i, $crate::error::ErrorKind)> {
            $submac!(i, $($args)*)
        }
    );
    ($vis:vis $name:ident<$i:ty,$o:ty,$e:ty>, $submac:ident!( $($args:tt)* )) => (
        $vis fn $name( i: $i ) -> $crate::IResult<$i, $o, $e> {
            $submac!(i, $($args)*)
        }
    );
    ($vis:vis $name:ident<$i:ty,$o:ty>, $submac:ident!( $($args:tt)* )) => (
        $vis fn $name( i: $i ) -> $crate::IResult<$i, $o, ($i, $crate::error::ErrorKind)> {
            $submac!(i, $($args)*)
        }
    );
    ($vis:vis $name:ident<$o:ty>, $submac:ident!( $($args:tt)* )) => (
        $vis fn $name( i: &[u8] ) -> $crate::IResult<&[u8], $o, (&[u8], $crate::error::ErrorKind)> {
            $submac!(i, $($args)*)
        }
    );
    ($vis:vis $name:ident, $submac:ident!( $($args:tt)* )) => (
        $vis fn $name( i: &[u8] ) -> $crate::IResult<&[u8], &[u8], (&[u8], $crate::error::ErrorKind)> {
            $submac!(i, $($args)*)
        }
    );
);

/// Makes a function from a parser combination with arguments.
///
/// ```ignore
/// //takes `&[u8]` as input
/// named_args!(tagged(open_tag: &[u8], close_tag: &[u8])<&str>,
///   delimited!(tag!(open_tag), map_res!(take!(4), str::from_utf8), tag!(close_tag))
/// );

/// //takes `&str` as input
/// named_args!(tagged(open_tag: &str, close_tag: &str)<&str, &str>,
///   delimited!(tag!(open_tag), take!(4), tag!(close_tag))
/// );
/// ```
///
/// Note: if using arguments that way gets hard to read, it is always
/// possible to write the equivalent parser definition manually, like
/// this:
///
/// ```ignore
/// fn tagged(input: &[u8], open_tag: &[u8], close_tag: &[u8]) -> IResult<&[u8], &str> {
///   // the first combinator in the tree gets the input as argument. It is then
///   // passed from one combinator to the next through macro rewriting
///   delimited!(input,
///     tag!(open_tag), take!(4), tag!(close_tag)
///   )
/// );
/// ```
///
#[macro_export(local_inner_macros)]
macro_rules! named_args {
    ($vis:vis $func_name:ident ( $( $arg:ident : $typ:ty ),* ) < $return_type:ty > , $submac:ident!( $($args:tt)* ) ) => {
        $vis fn $func_name(input: &[u8], $( $arg : $typ ),*) -> $crate::IResult<&[u8], $return_type> {
            $submac!(input, $($args)*)
        }
    };

    ($vis:vis $func_name:ident < 'a > ( $( $arg:ident : $typ:ty ),* ) < $return_type:ty > , $submac:ident!( $($args:tt)* ) ) => {
        $vis fn $func_name<'this_is_probably_unique_i_hope_please, 'a>(
          input: &'this_is_probably_unique_i_hope_please [u8], $( $arg : $typ ),*) ->
          $crate::IResult<&'this_is_probably_unique_i_hope_please [u8], $return_type>
        {
          $submac!(input, $($args)*)
        }
    };

    ($vis:vis $func_name:ident ( $( $arg:ident : $typ:ty ),* ) < $input_type:ty, $return_type:ty > , $submac:ident!( $($args:tt)* ) ) => {
        $vis fn $func_name(input: $input_type, $( $arg : $typ ),*) -> $crate::IResult<$input_type, $return_type> {
            $submac!(input, $($args)*)
        }
    };

    ($vis:vis $func_name:ident < 'a > ( $( $arg:ident : $typ:ty ),* ) < $input_type:ty, $return_type:ty > , $submac:ident!( $($args:tt)* ) ) => {
        $vis fn $func_name<'a>(
          input: $input_type, $( $arg : $typ ),*)
          -> $crate::IResult<$input_type, $return_type>
        {
            $submac!(input, $($args)*)
        }
    };
}

/// Makes a function from a parser combination, with attributes
///
/// The usage of this macro is almost identical to `named!`, except that
/// you also pass attributes to be attached to the generated function.
/// This is ideal for adding documentation to your parser.
///
/// Create my_function as if you wrote it with the doc comment /// My Func:
/// ```
/// # use nom::{named_attr, tag};
/// named_attr!(#[doc = "My Func"], my_function( &[u8] ) -> &[u8], tag!("abcd"));
/// ```
/// Also works for pub functions, and multiple lines:
/// ```
/// # use nom::{named_attr, tag};
/// named_attr!(#[doc = "My Func\nRecognise abcd"], pub my_function, tag!("abcd"));
/// ```
/// Multiple attributes can be passed if required:
/// ```
/// # use nom::{named_attr, tag};
/// named_attr!(#[doc = "My Func"] #[inline(always)], pub my_function, tag!("abcd"));
/// ```
#[macro_export(local_inner_macros)]
macro_rules! named_attr (
    ($(#[$attr:meta])*, $vis:vis $name:ident( $i:ty ) -> $o:ty, $submac:ident!( $($args:tt)* )) => (
        $(#[$attr])*
        $vis fn $name( i: $i ) -> $crate::IResult<$i,$o, ($i, $crate::error::ErrorKind)> {
            $submac!(i, $($args)*)
        }
    );
    ($(#[$attr:meta])*, $vis:vis $name:ident<$i:ty,$o:ty,$e:ty>, $submac:ident!( $($args:tt)* )) => (
        $(#[$attr])*
        $vis fn $name( i: $i ) -> $crate::IResult<$i, $o, $e> {
            $submac!(i, $($args)*)
        }
    );
    ($(#[$attr:meta])*, $vis:vis $name:ident<$i:ty,$o:ty>, $submac:ident!( $($args:tt)* )) => (
        $(#[$attr])*
        $vis fn $name( i: $i ) -> $crate::IResult<$i, $o, ($i, $crate::error::ErrorKind)> {
            $submac!(i, $($args)*)
        }
    );
    ($(#[$attr:meta])*, $vis:vis $name:ident<$o:ty>, $submac:ident!( $($args:tt)* )) => (
        $(#[$attr])*
        $vis fn $name( i: &[u8] ) -> $crate::IResult<&[u8], $o, (&[u8], $crate::error::ErrorKind)> {
            $submac!(i, $($args)*)
        }
    );
    ($(#[$attr:meta])*, $vis:vis $name:ident, $submac:ident!( $($args:tt)* )) => (
        $(#[$attr])*
        $vis fn $name<'a>( i: &'a [u8] ) -> $crate::IResult<&[u8], &[u8], (&[u8], $crate::error::ErrorKind)> {
            $submac!(i, $($args)*)
        }
    );
);

/// Used to wrap common expressions and function as macros
///
/// ```
/// # #[macro_use] extern crate nom;
/// # use nom::IResult;
/// # fn main() {
///   fn take_wrapper(input: &[u8], i: u8) -> IResult<&[u8], &[u8]> { take!(input, i * 10) }
///
///   // will make a parser taking 20 bytes
///   named!(parser, call!(take_wrapper, 2));
/// # }
/// ```
#[macro_export(local_inner_macros)]
macro_rules! call (
  ($i:expr, $fun:expr) => ( $fun( $i ) );
  ($i:expr, $fun:expr, $($args:expr),* ) => ( $fun( $i, $($args),* ) );
);

//FIXME: error rewrite
/// Prevents backtracking if the child parser fails
///
/// This parser will do an early return instead of sending
/// its result to the parent parser.
///
/// If another `return_error!` combinator is present in the parent
/// chain, the error will be wrapped and another early
/// return will be made.
///
/// This makes it easy to build report on which parser failed,
/// where it failed in the input, and the chain of parsers
/// that led it there.
///
/// Additionally, the error chain contains number identifiers
/// that can be matched to provide useful error messages.
///
/// ```
/// # #[macro_use] extern crate nom;
/// # use nom::Err;
/// # use nom::error::ErrorKind;
/// # fn main() {
///     named!(err_test<&[u8], &[u8]>, alt!(
///       tag!("abcd") |
///       preceded!(tag!("efgh"), return_error!(ErrorKind::Eof,
///           do_parse!(
///                  tag!("ijkl")                                        >>
///             res: return_error!(ErrorKind::Tag, tag!("mnop")) >>
///             (res)
///           )
///         )
///       )
///     ));
///     let a = &b"efghblah"[..];
///     let b = &b"efghijklblah"[..];
///     let c = &b"efghijklmnop"[..];
///
///     let blah = &b"blah"[..];
///
///     let res_a = err_test(a);
///     let res_b = err_test(b);
///     let res_c = err_test(c);
///     assert_eq!(res_a, Err(Err::Failure(error_node_position!(blah, ErrorKind::Eof, error_position!(blah, ErrorKind::Tag)))));
///     assert_eq!(res_b, Err(Err::Failure(error_node_position!(&b"ijklblah"[..], ErrorKind::Eof,
///       error_node_position!(blah, ErrorKind::Tag, error_position!(blah, ErrorKind::Tag))))
///     ));
/// # }
/// ```
///
#[macro_export(local_inner_macros)]
macro_rules! return_error (
  ($i:expr, $code:expr, $submac:ident!( $($args:tt)* )) => (
    {
      use $crate::lib::std::result::Result::*;
      use $crate::Err;

      let i_ = $i.clone();
      let cl = || {
        $submac!(i_, $($args)*)
      };

      match cl() {
        Err(Err::Incomplete(x)) => Err(Err::Incomplete(x)),
        Ok((i, o))              => Ok((i, o)),
        Err(Err::Error(e)) | Err(Err::Failure(e)) => {
          return Err(Err::Failure($crate::error::append_error($i, $code, e)))
        }
      }
    }
  );
  ($i:expr, $code:expr, $f:expr) => (
    return_error!($i, $code, call!($f));
  );
  ($i:expr, $submac:ident!( $($args:tt)* )) => (
    {
      use $crate::lib::std::result::Result::*;
      use $crate::Err;

      let i_ = $i.clone();
      let cl = || {
        $submac!(i_, $($args)*)
      };

      match cl() {
        Err(Err::Incomplete(x)) => Err(Err::Incomplete(x)),
        Ok((i, o))              => Ok((i, o)),
        Err(Err::Error(e)) | Err(Err::Failure(e)) => {
          return Err(Err::Failure(e))
        }
      }
    }
  );
  ($i:expr, $f:expr) => (
    return_error!($i, call!($f));
  );
);

//FIXME: error rewrite
/// Add an error if the child parser fails
///
/// While `return_error!` does an early return and avoids backtracking,
/// add_return_error! backtracks normally. It just provides more context
/// for an error
///
/// ```
/// # #[macro_use] extern crate nom;
/// # use std::collections;
/// # use nom::Err;
/// # use nom::error::ErrorKind;
/// # fn main() {
///     named!(err_test, add_return_error!(ErrorKind::Tag, tag!("abcd")));
///
///     let a = &b"efghblah"[..];
///     let res_a = err_test(a);
///     assert_eq!(res_a, Err(Err::Error(error_node_position!(a, ErrorKind::Tag, error_position!(a, ErrorKind::Tag)))));
/// # }
/// ```
///
#[macro_export(local_inner_macros)]
macro_rules! add_return_error (
  ($i:expr, $code:expr, $submac:ident!( $($args:tt)* )) => (
    {
      use $crate::lib::std::result::Result::*;
      use $crate::{Err,error::ErrorKind};

      match $submac!($i, $($args)*) {
        Ok((i, o)) => Ok((i, o)),
        Err(Err::Error(e)) => {
          Err(Err::Error(error_node_position!($i, $code, e)))
        },
        Err(Err::Failure(e)) => {
          Err(Err::Failure(error_node_position!($i, $code, e)))
        },
        Err(e) => Err(e),
      }
    }
  );
  ($i:expr, $code:expr, $f:expr) => (
    add_return_error!($i, $code, call!($f));
  );
);

/// replaces a `Incomplete` returned by the child parser
/// with an `Error`
///
/// ```
/// # #[macro_use] extern crate nom;
/// # use std::collections;
/// # use nom::Err;
/// # use nom::error::ErrorKind;
/// # fn main() {
///     named!(take_5, complete!(take!(5)));
///
///     let a = &b"abcd"[..];
///     let res_a = take_5(a);
///     assert_eq!(res_a, Err(Err::Error(error_position!(a, ErrorKind::Complete))));
/// # }
/// ```
///
#[macro_export(local_inner_macros)]
macro_rules! complete (
  ($i:expr, $submac:ident!( $($args:tt)* )) => (
    $crate::combinator::completec($i, move |i| { $submac!(i, $($args)*) })
  );
  ($i:expr, $f:expr) => (
    complete!($i, call!($f));
  );
);

/// A bit like `std::try!`, this macro will return the remaining input and
/// parsed value if the child parser returned `Ok`, and will do an early
/// return for the `Err` side.
///
/// this can provide more flexibility than `do_parse!` if needed
///
/// ```
/// # #[macro_use] extern crate nom;
/// # use nom::Err;
/// # use nom::error::ErrorKind;
/// # use nom::IResult;
///
///  fn take_add(input:&[u8], size: u8) -> IResult<&[u8], &[u8]> {
///    let (i1, length)     = try_parse!(input, map_opt!(nom::number::streaming::be_u8, |sz| size.checked_add(sz)));
///    let (i2, data)   = try_parse!(i1, take!(length));
///    return Ok((i2, data));
///  }
/// # fn main() {
/// let arr1 = [1, 2, 3, 4, 5];
/// let r1 = take_add(&arr1[..], 1);
/// assert_eq!(r1, Ok((&[4,5][..], &[2,3][..])));
///
/// let arr2 = [0xFE, 2, 3, 4, 5];
/// // size is overflowing
/// let r1 = take_add(&arr2[..], 42);
/// assert_eq!(r1, Err(Err::Error(error_position!(&[254, 2,3,4,5][..], ErrorKind::MapOpt))));
/// # }
/// ```
#[macro_export(local_inner_macros)]
macro_rules! try_parse (
  ($i:expr, $submac:ident!( $($args:tt)* )) => ({
    use $crate::lib::std::result::Result::*;

    match $submac!($i, $($args)*) {
      Ok((i,o)) => (i,o),
      Err(e)    => return Err(e),
    }
    });
  ($i:expr, $f:expr) => (
    try_parse!($i, call!($f))
  );
);

/// `map!(I -> IResult<I, O>, O -> P) => I -> IResult<I, P>`
///
/// maps a function on the result of a parser
///
/// ```rust
/// # #[macro_use] extern crate nom;
/// # use nom::{Err,error::ErrorKind, IResult};
/// use nom::character::complete::digit1;
/// # fn main() {
///
/// named!(parse<&str, usize>, map!(digit1, |s| s.len()));
///
/// // the parser will count how many characters were returned by digit1
/// assert_eq!(parse("123456"), Ok(("", 6)));
///
/// // this will fail if digit1 fails
/// assert_eq!(parse("abc"), Err(Err::Error(error_position!("abc", ErrorKind::Digit))));
/// # }
/// ```
#[macro_export(local_inner_macros)]
macro_rules! map(
  // Internal parser, do not use directly
  (__impl $i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
    $crate::combinator::mapc($i, move |i| {$submac!(i, $($args)*)}, $g)
  );
  ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
    map!(__impl $i, $submac!($($args)*), $g);
  );
  ($i:expr, $f:expr, $g:expr) => (
    map!(__impl $i, call!($f), $g);
  );
);

/// `map_res!(I -> IResult<I, O>, O -> Result<P>) => I -> IResult<I, P>`
/// maps a function returning a Result on the output of a parser
///
/// ```rust
/// # #[macro_use] extern crate nom;
/// # use nom::{Err,error::ErrorKind, IResult};
/// use nom::character::complete::digit1;
/// # fn main() {
///
/// named!(parse<&str, u8>, map_res!(digit1, |s: &str| s.parse::<u8>()));
///
/// // the parser will convet the result of digit1 to a number
/// assert_eq!(parse("123"), Ok(("", 123)));
///
/// // this will fail if digit1 fails
/// assert_eq!(parse("abc"), Err(Err::Error(error_position!("abc", ErrorKind::Digit))));
///
/// // this will fail if the mapped function fails (a `u8` is too small to hold `123456`)
/// assert_eq!(parse("123456"), Err(Err::Error(error_position!("123456", ErrorKind::MapRes))));
/// # }
/// ```
#[macro_export(local_inner_macros)]
macro_rules! map_res (
  // Internal parser, do not use directly
  (__impl $i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
    $crate::combinator::map_resc($i, move |i| {$submac!(i, $($args)*)}, move |i| {$submac2!(i, $($args2)*)})
  );
  ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
    map_res!(__impl $i, $submac!($($args)*), call!($g));
  );
  ($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
    map_res!(__impl $i, $submac!($($args)*), $submac2!($($args2)*));
  );
  ($i:expr, $f:expr, $g:expr) => (
    map_res!(__impl $i, call!($f), call!($g));
  );
  ($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
    map_res!(__impl $i, call!($f), $submac!($($args)*));
  );
);

/// `map_opt!(I -> IResult<I, O>, O -> Option<P>) => I -> IResult<I, P>`
/// maps a function returning an Option on the output of a parser
///
/// ```rust
/// # #[macro_use] extern crate nom;
/// # use nom::{Err,error::ErrorKind, IResult};
/// use nom::character::complete::digit1;
/// # fn main() {
///
/// named!(parser<&str, u8>, map_opt!(digit1, |s: &str| s.parse::<u8>().ok()));
///
/// // the parser will convert the result of digit1 to a number
/// assert_eq!(parser("123"), Ok(("", 123)));
///
/// // this will fail if digit1 fails
/// assert_eq!(parser("abc"), Err(Err::Error(("abc", ErrorKind::Digit))));
///
/// // this will fail if the mapped function fails (a `u8` is too small to hold `123456`)
/// assert_eq!(parser("123456"), Err(Err::Error(("123456", ErrorKind::MapOpt))));
/// # }
/// ```
#[macro_export(local_inner_macros)]
macro_rules! map_opt (
  // Internal parser, do not use directly
  (__impl $i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
    $crate::combinator::map_optc($i, move |i| {$submac!(i, $($args)*)}, move |i| {$submac2!(i, $($args2)*)})
  );
  ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
    map_opt!(__impl $i, $submac!($($args)*), call!($g));
  );
  ($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
    map_opt!(__impl $i, $submac!($($args)*), $submac2!($($args2)*));
  );
  ($i:expr, $f:expr, $g:expr) => (
    map_opt!(__impl $i, call!($f), call!($g));
  );
  ($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
    map_opt!(__impl $i, call!($f), $submac!($($args)*));
  );
);

/// `parse_to!(O) => I -> IResult<I, O>`
/// uses the `parse` method from `std::str::FromStr` to convert the current
/// input to the specified type
///
/// this will completely consume the input
///
/// ```rust
/// # #[macro_use] extern crate nom;
/// # use nom::{Err,error::ErrorKind, IResult};
/// use nom::character::complete::digit1;
/// # fn main() {
///
/// named!(parser<&str, u8>, parse_to!(u8));
///
/// assert_eq!(parser("123"), Ok(("", 123)));
///
/// assert_eq!(parser("abc"), Err(Err::Error(("abc", ErrorKind::ParseTo))));
///
/// // this will fail if the mapped function fails (a `u8` is too small to hold `123456`)
/// assert_eq!(parser("123456"), Err(Err::Error(("123456", ErrorKind::ParseTo))));
/// # }
/// ```
#[macro_export(local_inner_macros)]
macro_rules! parse_to (
  ($i:expr, $t:ty ) => (
    {
      use $crate::lib::std::result::Result::*;
      use $crate::lib::std::option::Option;
      use $crate::lib::std::option::Option::*;
      use $crate::{Err,error::ErrorKind};

      use $crate::ParseTo;
      use $crate::Slice;
      use $crate::InputLength;

      let res: Option<$t> = ($i).parse_to();
      match res {
        Some(output) => Ok(($i.slice($i.input_len()..), output)),
        None         => Err(Err::Error($crate::error::make_error($i, ErrorKind::ParseTo)))
      }
    }
  );
);

/// `verify!(I -> IResult<I, O>, O -> bool) => I -> IResult<I, O>`
/// returns the result of the child parser if it satisfies a verification function
///
/// ```
/// # #[macro_use] extern crate nom;
/// # fn main() {
///  named!(check<u32>, verify!(nom::number::streaming::be_u32, |val: &u32| *val < 3));
/// # }
/// ```
#[macro_export(local_inner_macros)]
macro_rules! verify (
  ($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
    $crate::combinator::verifyc($i, |i| $submac!(i, $($args)*), $g)
  );
  ($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
    $crate::combinator::verifyc($i, |i| $submac!(i, $($args)*), |&o| $submac2!(o, $($args2)*))
  );
  ($i:expr, $f:expr, $g:expr) => (
    $crate::combinator::verify($f, $g)($i)
  );
  ($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
    $crate::combinator::verify($f, |&o| $submac2!(o, $($args)*))($i)
  );
);

/// `value!(T, R -> IResult<R, S> ) => R -> IResult<R, T>`
///
/// or `value!(T) => R -> IResult<R, T>`
///
/// If the child parser was successful, return the value.
/// If no child parser is provided, always return the value
///
/// ```
/// # #[macro_use] extern crate nom;
/// # fn main() {
///  named!(x<u8>, value!(42, delimited!(tag!("<!--"), take!(5), tag!("-->"))));
///  named!(y<u8>, delimited!(tag!("<!--"), value!(42), tag!("-->")));
///  let r = x(&b"<!-- abc --> aaa"[..]);
///  assert_eq!(r, Ok((&b" aaa"[..], 42)));
///
///  let r2 = y(&b"<!----> aaa"[..]);
///  assert_eq!(r2, Ok((&b" aaa"[..], 42)));
/// # }
/// ```
#[macro_export(local_inner_macros)]
macro_rules! value (
  ($i:expr, $res:expr, $submac:ident!( $($args:tt)* )) => (
    $crate::combinator::valuec($i, $res, |i| $submac!(i, $($args)*))
  );
  ($i:expr, $res:expr, $f:expr) => (
    $crate::combinator::valuec($i, $res, $f)
  );
  ($i:expr, $res:expr) => (
    {
      let res: $crate::IResult<_,_> = Ok(($i, $res));
      res
    }
  );
);

/// `opt!(I -> IResult<I,O>) => I -> IResult<I, Option<O>>`
/// make the underlying parser optional
///
/// returns an Option of the returned type. This parser returns `Some(result)` if the child parser
/// succeeds,`None` if it fails, and `Incomplete` if it did not have enough data to decide
///
/// *Warning*: if you are using `opt` for some kind of optional ending token (like an end of line),
/// you should combine it with `complete` to make sure it works.
///
/// As an example, `opt!(tag!("\r\n"))` will return `Incomplete` if it receives an empty input,
/// because `tag` does not have enough input to decide.
/// On the contrary, `opt!(complete!(tag!("\r\n")))` would return `None` as produced value,
/// since `complete!` transforms an `Incomplete` in an `Error`.
///
/// ```
/// # #[macro_use] extern crate nom;
/// # fn main() {
///  named!( o<&[u8], Option<&[u8]> >, opt!( tag!( "abcd" ) ) );
///
///  let a = b"abcdef";
///  let b = b"bcdefg";
///  assert_eq!(o(&a[..]), Ok((&b"ef"[..], Some(&b"abcd"[..]))));
///  assert_eq!(o(&b[..]), Ok((&b"bcdefg"[..], None)));
///  # }
/// ```
#[macro_export(local_inner_macros)]
macro_rules! opt(
  ($i:expr, $submac:ident!( $($args:tt)* )) => (
    {
      $crate::combinator::optc($i, |i| $submac!(i, $($args)*))
    }
  );
  ($i:expr, $f:expr) => (
    $crate::combinator::opt($f)($i)
  );
);

/// `opt_res!(I -> IResult<I,O>) => I -> IResult<I, Result<nom::Err,O>>`
/// make the underlying parser optional
///
/// returns a Result, with Err containing the parsing error
///
/// ```ignore
/// # #[macro_use] extern crate nom;
/// # use nom::ErrorKind;
/// # fn main() {
///  named!( o<&[u8], Result<&[u8], nom::Err<&[u8]> > >, opt_res!( tag!( "abcd" ) ) );
///
///  let a = b"abcdef";
///  let b = b"bcdefg";
///  assert_eq!(o(&a[..]), Ok((&b"ef"[..], Ok(&b"abcd"[..])));
///  assert_eq!(o(&b[..]), Ok((&b"bcdefg"[..], Err(error_position!(&b[..], ErrorKind::Tag))));
///  # }
/// ```
#[macro_export(local_inner_macros)]
macro_rules! opt_res (
  ($i:expr, $submac:ident!( $($args:tt)* )) => (
    {
      use $crate::lib::std::result::Result::*;
      use $crate::Err;

      let i_ = $i.clone();
      match $submac!(i_, $($args)*) {
        Ok((i,o))          => Ok((i,  Ok(o))),
        Err(Err::Error(e)) => Ok(($i, Err(Err::Error(e)))),
        // in case of failure, we return a real error
        Err(e)             => Err(e)
      }
    }
  );
  ($i:expr, $f:expr) => (
    opt_res!($i, call!($f));
  );
);

/// `cond!(bool, I -> IResult<I,O>) => I -> IResult<I, Option<O>>`
/// Conditional combinator
///
/// Wraps another parser and calls it if the
/// condition is met. This combinator returns
/// an Option of the return type of the child
/// parser.
///
/// This is especially useful if a parser depends
/// on the value returned by a preceding parser in
/// a `do_parse!`.
///
/// ```
/// # #[macro_use] extern crate nom;
/// # use nom::IResult;
/// # fn main() {
///  fn f_true(i: &[u8]) -> IResult<&[u8], Option<&[u8]>> {
///    cond!(i, true, tag!("abcd"))
///  }
///
///  fn f_false(i: &[u8]) -> IResult<&[u8], Option<&[u8]>> {
///    cond!(i, false, tag!("abcd"))
///  }
///
///  let a = b"abcdef";
///  assert_eq!(f_true(&a[..]), Ok((&b"ef"[..], Some(&b"abcd"[..]))));
///
///  assert_eq!(f_false(&a[..]), Ok((&b"abcdef"[..], None)));
///  # }
/// ```
///
#[macro_export(local_inner_macros)]
macro_rules! cond(
  ($i:expr, $cond:expr, $submac:ident!( $($args:tt)* )) => (
    $crate::combinator::condc($i, $cond, |i|  $submac!(i, $($args)*) )
  );
  ($i:expr, $cond:expr, $f:expr) => (
    $crate::combinator::cond($cond, $f)($i)
  );
);

/// `peek!(I -> IResult<I,O>) => I -> IResult<I, O>`
/// returns a result without consuming the input
///
/// the embedded parser may return Err(Err::Incomplete
///
/// ```
/// # #[macro_use] extern crate nom;
/// # fn main() {
///  named!(ptag, peek!( tag!( "abcd" ) ) );
///
///  let r = ptag(&b"abcdefgh"[..]);
///  assert_eq!(r, Ok((&b"abcdefgh"[..], &b"abcd"[..])));
/// # }
/// ```
#[macro_export(local_inner_macros)]
macro_rules! peek(
  ($i:expr, $submac:ident!( $($args:tt)* )) => (
    $crate::combinator::peekc($i, |i| $submac!(i, $($args)*))
  );
  ($i:expr, $f:expr) => (
    peek!($i, call!($f));
    $crate::combinator::peek($f)($i)
  );
);

/// `not!(I -> IResult<I,O>) => I -> IResult<I, ()>`
/// returns a result only if the embedded parser returns Error or Err(Err::Incomplete)
/// does not consume the input
///
/// ```
/// # #[macro_use] extern crate nom;
/// # use nom::Err;
/// # use nom::error::ErrorKind;
/// # fn main() {
/// named!(not_e, do_parse!(
///     res: tag!("abc")      >>
///          not!(char!('e')) >>
///     (res)
/// ));
///
/// let r = not_e(&b"abcd"[..]);
/// assert_eq!(r, Ok((&b"d"[..], &b"abc"[..])));
///
/// let r2 = not_e(&b"abce"[..]);
/// assert_eq!(r2, Err(Err::Error(error_position!(&b"e"[..], ErrorKind::Not))));
/// # }
/// ```
#[macro_export(local_inner_macros)]
macro_rules! not(
  ($i:expr, $submac:ident!( $($args:tt)* )) => (
    $crate::combinator::notc($i, |i| $submac!(i, $($args)*))
  );
  ($i:expr, $f:expr) => (
    $crate::combinator::not($f)($i)
  );
);

/// `tap!(name: I -> IResult<I,O> => { block }) => I -> IResult<I, O>`
/// allows access to the parser's result without affecting it
///
/// ```
/// # #[macro_use] extern crate nom;
/// # use std::str;
/// # fn main() {
///  named!(ptag, tap!(res: tag!( "abcd" ) => { println!("recognized {}", str::from_utf8(res).unwrap()) } ) );
///
///  let r = ptag(&b"abcdefgh"[..]);
///  assert_eq!(r, Ok((&b"efgh"[..], &b"abcd"[..])));
/// # }
/// ```
#[macro_export(local_inner_macros)]
macro_rules! tap (
  ($i:expr, $name:ident : $submac:ident!( $($args:tt)* ) => $e:expr) => (
    {
      use $crate::lib::std::result::Result::*;
      use $crate::{Err,Needed,IResult};

      match $submac!($i, $($args)*) {
        Ok((i,o)) => {
          let $name = o;
          $e;
          Ok((i, $name))
        },
        Err(e)    => Err(Err::convert(e)),
      }
    }
  );
  ($i:expr, $name: ident: $f:expr => $e:expr) => (
    tap!($i, $name: call!($f) => $e);
  );
);

/// `eof!()` returns its input if it is at the end of input data
///
/// When we're at the end of the data, this combinator
/// will succeed
///
///
/// ```
/// # #[macro_use] extern crate nom;
/// # use std::str;
/// # use nom::{Err, error::ErrorKind};
/// # fn main() {
///  named!(parser, eof!());
///
///  assert_eq!(parser(&b"abc"[..]), Err(Err::Error((&b"abc"[..], ErrorKind::Eof))));
///  assert_eq!(parser(&b""[..]), Ok((&b""[..], &b""[..])));
/// # }
/// ```
#[macro_export(local_inner_macros)]
macro_rules! eof (
  ($i:expr,) => (
    {
      use $crate::lib::std::result::Result::*;
      use $crate::{Err,error::ErrorKind};

      use $crate::InputLength;
      if ($i).input_len() == 0 {
        Ok(($i, $i))
      } else {
        Err(Err::Error(error_position!($i, ErrorKind::Eof)))
      }
    }
  );
);

/// `exact!()` will fail if the child parser does not consume the whole data
///
/// TODO: example
#[macro_export(local_inner_macros)]
macro_rules! exact (
  ($i:expr, $submac:ident!( $($args:tt)* )) => ({
      terminated!($i, $submac!( $($args)*), eof!())
  });
  ($i:expr, $f:expr) => (
    exact!($i, call!($f));
  );
);

/// `recognize!(I -> IResult<I, O> ) => I -> IResult<I, I>`
/// if the child parser was successful, return the consumed input as produced value
///
/// ```
/// # #[macro_use] extern crate nom;
/// # fn main() {
///  named!(x, recognize!(delimited!(tag!("<!--"), take!(5), tag!("-->"))));
///  let r = x(&b"<!-- abc --> aaa"[..]);
///  assert_eq!(r, Ok((&b" aaa"[..], &b"<!-- abc -->"[..])));
/// # }
/// ```
#[macro_export(local_inner_macros)]
macro_rules! recognize (
  ($i:expr, $submac:ident!( $($args:tt)* )) => (
    $crate::combinator::recognizec($i, |i| $submac!(i, $($args)*))
  );
  ($i:expr, $f:expr) => (
    $crate::combinator::recognize($f)($i)
  );
);

#[cfg(test)]
mod tests {
  use crate::internal::{Err, IResult, Needed};
  use crate::error::ParseError;
  use crate::error::ErrorKind;
  #[cfg(feature = "alloc")]
  use crate::lib::std::boxed::Box;

  // reproduce the tag and take macros, because of module import order
  macro_rules! tag (
    ($i:expr, $tag: expr) => ({
      use $crate::lib::std::result::Result::*;
      use $crate::{Err,Needed,IResult,error::ErrorKind};
      use $crate::{Compare,CompareResult,InputLength,Slice};

      let res: IResult<_,_> = match ($i).compare($tag) {
        CompareResult::Ok => {
          let blen = $tag.input_len();
          Ok(($i.slice(blen..), $i.slice(..blen)))
        },
        CompareResult::Incomplete => {
          Err(Err::Incomplete(Needed::Size($tag.input_len())))
        },
        CompareResult::Error => {
          let e:ErrorKind = ErrorKind::Tag;
          Err(Err::Error($crate::error::make_error($i, e)))
        }
      };
      res
      });
  );

  macro_rules! take(
    ($i:expr, $count:expr) => (
      {
        let cnt = $count as usize;
        let res:IResult<&[u8],&[u8]> = if $i.len() < cnt {
          Err($crate::Err::Incomplete($crate::Needed::Size(cnt)))
        } else {
          Ok((&$i[cnt..],&$i[0..cnt]))
        };
        res
      }
    );
  );

  mod pub_named_mod {
    named!(pub tst, tag!("abcd"));
  }

  #[test]
  fn pub_named_test() {
    let a = &b"abcd"[..];
    let res = pub_named_mod::tst(a);
    assert_eq!(res, Ok((&b""[..], a)));
  }

  mod pub_crate_named_mod {
    named!(pub(crate) tst, tag!("abcd"));
  }

  #[test]
  fn pub_crate_named_test() {
    let a = &b"abcd"[..];
    let res = pub_crate_named_mod::tst(a);
    assert_eq!(res, Ok((&b""[..], a)));
  }

  #[test]
  fn apply_test() {
    fn sum2(a: u8, b: u8) -> u8 {
      a + b
    }
    fn sum3(a: u8, b: u8, c: u8) -> u8 {
      a + b + c
    }
    let a = call!(1, sum2, 2);
    let b = call!(1, sum3, 2, 3);

    assert_eq!(a, 3);
    assert_eq!(b, 6);
  }

  #[test]
  fn opt() {
    named!(opt_abcd<&[u8],Option<&[u8]> >, opt!(tag!("abcd")));

    let a = &b"abcdef"[..];
    let b = &b"bcdefg"[..];
    let c = &b"ab"[..];
    assert_eq!(opt_abcd(a), Ok((&b"ef"[..], Some(&b"abcd"[..]))));
    assert_eq!(opt_abcd(b), Ok((&b"bcdefg"[..], None)));
    assert_eq!(opt_abcd(c), Err(Err::Incomplete(Needed::Size(4))));
  }

  #[test]
  fn opt_res() {
    named!(opt_res_abcd<&[u8], Result<&[u8], Err<(&[u8], ErrorKind)>> >, opt_res!(tag!("abcd")));

    let a = &b"abcdef"[..];
    let b = &b"bcdefg"[..];
    let c = &b"ab"[..];
    assert_eq!(opt_res_abcd(a), Ok((&b"ef"[..], Ok(&b"abcd"[..]))));
    assert_eq!(
      opt_res_abcd(b),
      Ok((
        &b"bcdefg"[..],
        Err(Err::Error(error_position!(b, ErrorKind::Tag)))
      ))
    );
    assert_eq!(opt_res_abcd(c), Err(Err::Incomplete(Needed::Size(4))));
  }

  use crate::lib::std::convert::From;
  #[derive(Debug, PartialEq)]
  pub struct CustomError(&'static str);
  impl<I> From<(I, ErrorKind)> for CustomError {
    fn from(_: (I, ErrorKind)) -> Self {
      CustomError("test")
    }
  }

  impl<I> ParseError<I> for CustomError {
    fn from_error_kind(_: I, _: ErrorKind) -> Self {
      CustomError("from_error_kind")
    }

    fn append(_: I, _: ErrorKind, _: CustomError) -> Self {
      CustomError("append")
    }
  }


  #[test]
  #[cfg(feature = "alloc")]
  fn cond() {
    fn f_true(i: &[u8]) -> IResult<&[u8], Option<&[u8]>, CustomError> {
      fix_error!(i, CustomError, cond!(true, tag!("abcd")))
    }

    fn f_false(i: &[u8]) -> IResult<&[u8], Option<&[u8]>, CustomError> {
      fix_error!(i, CustomError, cond!(false, tag!("abcd")))
    }

    assert_eq!(f_true(&b"abcdef"[..]), Ok((&b"ef"[..], Some(&b"abcd"[..]))));
    assert_eq!(f_true(&b"ab"[..]), Err(Err::Incomplete(Needed::Size(4))));
    assert_eq!(f_true(&b"xxx"[..]), Err(Err::Error(CustomError("test"))));

    assert_eq!(f_false(&b"abcdef"[..]), Ok((&b"abcdef"[..], None)));
    assert_eq!(f_false(&b"ab"[..]), Ok((&b"ab"[..], None)));
    assert_eq!(f_false(&b"xxx"[..]), Ok((&b"xxx"[..], None)));
  }

  #[test]
  #[cfg(feature = "alloc")]
  fn cond_wrapping() {
    // Test that cond!() will wrap a given identifier in the call!() macro.
    named!(tag_abcd, tag!("abcd"));
    fn f_true(i: &[u8]) -> IResult<&[u8], Option<&[u8]>, CustomError> {
      fix_error!(i, CustomError, cond!(true, tag_abcd))
    }

    fn f_false(i: &[u8]) -> IResult<&[u8], Option<&[u8]>, CustomError> {
      fix_error!(i, CustomError, cond!(false, tag_abcd))
    }

    assert_eq!(f_true(&b"abcdef"[..]), Ok((&b"ef"[..], Some(&b"abcd"[..]))));
    assert_eq!(f_true(&b"ab"[..]), Err(Err::Incomplete(Needed::Size(4))));
    assert_eq!(f_true(&b"xxx"[..]), Err(Err::Error(CustomError("test"))));

    assert_eq!(f_false(&b"abcdef"[..]), Ok((&b"abcdef"[..], None)));
    assert_eq!(f_false(&b"ab"[..]), Ok((&b"ab"[..], None)));
    assert_eq!(f_false(&b"xxx"[..]), Ok((&b"xxx"[..], None)));
  }

  #[test]
  fn peek() {
    named!(peek_tag<&[u8],&[u8]>, peek!(tag!("abcd")));

    assert_eq!(peek_tag(&b"abcdef"[..]), Ok((&b"abcdef"[..], &b"abcd"[..])));
    assert_eq!(peek_tag(&b"ab"[..]), Err(Err::Incomplete(Needed::Size(4))));
    assert_eq!(
      peek_tag(&b"xxx"[..]),
      Err(Err::Error(error_position!(&b"xxx"[..], ErrorKind::Tag)))
    );
  }

  #[test]
  fn not() {
    named!(not_aaa<()>, not!(tag!("aaa")));
    assert_eq!(
      not_aaa(&b"aaa"[..]),
      Err(Err::Error(error_position!(&b"aaa"[..], ErrorKind::Not)))
    );
    assert_eq!(not_aaa(&b"aa"[..]), Err(Err::Incomplete(Needed::Size(3))));
    assert_eq!(not_aaa(&b"abcd"[..]), Ok((&b"abcd"[..], ())));
  }

  #[test]
  fn verify() {
    named!(test, verify!(take!(5), |slice: &[u8]| slice[0] == b'a'));
    assert_eq!(test(&b"bcd"[..]), Err(Err::Incomplete(Needed::Size(5))));
    assert_eq!(
      test(&b"bcdefg"[..]),
      Err(Err::Error(error_position!(
        &b"bcdefg"[..],
        ErrorKind::Verify
      )))
    );
    assert_eq!(test(&b"abcdefg"[..]), Ok((&b"fg"[..], &b"abcde"[..])));
  }

  #[test]
  fn parse_to() {
    let res: IResult<_, _, (&str, ErrorKind)> = parse_to!("ab", usize);

    assert_eq!(
      res,
      Err(Err::Error(error_position!(
        "ab",
        ErrorKind::ParseTo
      )))
    );

    let res: IResult<_, _, (&str, ErrorKind)> = parse_to!("42", usize);

    assert_eq!(res, Ok(("", 42)));
    //assert_eq!(ErrorKind::convert(ErrorKind::ParseTo), ErrorKind::ParseTo::<u64>);
  }

}
