Skip to content

Commit

Permalink
last code examples
Browse files Browse the repository at this point in the history
remove expr_opt and expr_res
  • Loading branch information
Geal committed May 9, 2019
1 parent ab5020c commit 4434f7f
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 77 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
- `take_until_and_consume`, `take_until_and_consume1`: they can be replaced with `take_until` combined with `take`
- `sized_buffer` and `length_bytes!`: they can be replaced with the `length_data` function
- `non_empty`, `begin` and `rest_s` function
- `cond_reduce!`, `cond_with_error!`, `closure!`, `apply`, `map_res_err!`
- `cond_reduce!`, `cond_with_error!`, `closure!`, `apply`, `map_res_err!`, `expr_opt!`, `expr_res!`
- `alt_complete`, `separated_list_complete`, `separated_nonempty_list_complete`

## 4.2.3 - 2019-03-23
Expand Down
122 changes: 52 additions & 70 deletions src/combinator/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,10 +447,9 @@ macro_rules! complete (
/// # use nom::IResult;
///
/// fn take_add(input:&[u8], size: u8) -> IResult<&[u8], &[u8]> {
/// let (i1, sz) = try_parse!(input, nom::number::streaming::be_u8);
/// let (i2, length) = try_parse!(i1, expr_opt!(size.checked_add(sz)));
/// let (i3, data) = try_parse!(i2, take!(length));
/// return Ok((i3, data));
/// 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];
Expand All @@ -460,7 +459,7 @@ macro_rules! complete (
/// let arr2 = [0xFE, 2, 3, 4, 5];
/// // size is overflowing
/// let r1 = take_add(&arr2[..], 42);
/// assert_eq!(r1, Err(Err::Error(error_position!(&[2,3,4,5][..], ErrorKind::ExprOpt))));
/// assert_eq!(r1, Err(Err::Error(error_position!(&[254, 2,3,4,5][..], ErrorKind::MapOpt))));
/// # }
/// ```
#[macro_export(local_inner_macros)]
Expand Down Expand Up @@ -554,6 +553,25 @@ macro_rules! map_res (

/// `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
Expand All @@ -579,6 +597,23 @@ macro_rules! map_opt (
/// 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 ) => (
Expand Down Expand Up @@ -670,70 +705,6 @@ macro_rules! value (
);
);

/// `expr_res!(Result<E, O>) => I -> IResult<I, O>`
/// evaluate an expression that returns a Result<T, E> and returns a Ok((I, T)) if Ok
///
/// See expr_opt for an example
#[macro_export(local_inner_macros)]
macro_rules! expr_res (
($i:expr, $e:expr) => (
{
use $crate::lib::std::result::Result::*;
use $crate::{Err,error::ErrorKind};

match $e {
Ok(output) => Ok(($i, output)),
Err(_) => Err(Err::Error(error_position!($i, ErrorKind::ExprRes)))
}
}
);
);

/// `expr_opt!(Option<O>) => I -> IResult<I, O>`
/// evaluate an expression that returns a Option<T> and returns a Ok((I,T)) if Some
///
/// Useful when doing computations in a chain
///
/// ```
/// # #[macro_use] extern crate nom;
/// # use nom::Err;
/// # use nom::IResult;
/// # use nom::{number::streaming::be_u8, error::ErrorKind};
///
/// fn take_add(input:&[u8], size: u8) -> IResult<&[u8], &[u8]> {
/// do_parse!(input,
/// sz: be_u8 >>
/// length: expr_opt!(size.checked_add(sz)) >> // checking for integer overflow (returns an Option)
/// data: take!(length) >>
/// (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!(&[2,3,4,5][..], ErrorKind::ExprOpt))));
/// # }
/// ```
#[macro_export(local_inner_macros)]
macro_rules! expr_opt (
($i:expr, $e:expr) => (
{
use $crate::lib::std::result::Result::*;
use $crate::{Err,error::ErrorKind};

match $e {
$crate::lib::std::option::Option::Some(output) => Ok(($i, output)),
$crate::lib::std::option::Option::None => Err(Err::Error(error_position!($i, ErrorKind::ExprOpt)))
}
}
);
);

/// `opt!(I -> IResult<I,O>) => I -> IResult<I, Option<O>>`
/// make the underlying parser optional
///
Expand Down Expand Up @@ -947,7 +918,18 @@ macro_rules! tap (
/// When we're at the end of the data, this combinator
/// will succeed
///
/// TODO: example
///
/// ```
/// # #[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,) => (
Expand Down
6 changes: 0 additions & 6 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,6 @@ pub enum ErrorKind {
MultiSpace,
LengthValueFn,
Eof,
ExprOpt,
ExprRes,
Switch,
TagBits,
OneOf,
Expand Down Expand Up @@ -226,8 +224,6 @@ pub fn error_to_u32(e: &ErrorKind) -> u32 {
ErrorKind::MultiSpace => 21,
ErrorKind::LengthValueFn => 22,
ErrorKind::Eof => 23,
ErrorKind::ExprOpt => 24,
ErrorKind::ExprRes => 25,
ErrorKind::Switch => 27,
ErrorKind::TagBits => 28,
ErrorKind::OneOf => 29,
Expand Down Expand Up @@ -290,8 +286,6 @@ impl ErrorKind {
ErrorKind::MultiSpace => "Multiple spaces",
ErrorKind::LengthValueFn => "LengthValueFn",
ErrorKind::Eof => "End of file",
ErrorKind::ExprOpt => "Evaluate Option",
ErrorKind::ExprRes => "Evaluate Result",
ErrorKind::Switch => "Switch",
ErrorKind::TagBits => "Tag on bitstream",
ErrorKind::OneOf => "OneOf",
Expand Down

0 comments on commit 4434f7f

Please sign in to comment.