//! 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, O -> P) => I -> IResult` /// /// 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, O -> Result

) => I -> IResult` /// 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::())); /// /// // the parser will convert 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, O -> Option

) => I -> IResult` /// 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::().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` /// 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, O -> bool) => I -> IResult` /// returns the result of the child parser if it satisfies a verification function /// /// ``` /// # #[macro_use] extern crate nom; /// # fn main() { /// named!(check, 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| $submac!(o, $($args)*))($i) ); ); /// `value!(T, R -> IResult ) => R -> IResult` /// /// or `value!(T) => R -> IResult` /// /// 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, value!(42, delimited!(tag!("")))); /// named!(y, delimited!(tag!(""))); /// let r = x(&b" 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) => ( Ok(($i, $res)) ); ); /// `opt!(I -> IResult) => I -> IResult>` /// 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 -> IResult>` /// 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 -> IResult>` /// 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 -> IResult` /// 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) => ( $crate::combinator::peek($f)($i) ); ); /// `not!(I -> IResult) => I -> IResult` /// 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 => { block }) => I -> IResult` /// 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 -> IResult` /// 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!("")))); /// let r = x(&b" aaa"[..]); /// assert_eq!(r, Ok((&b" aaa"[..], &b""[..]))); /// # } /// ``` #[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 From<(I, ErrorKind)> for CustomError { fn from(_: (I, ErrorKind)) -> Self { CustomError("test") } } impl ParseError 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::); } }