Repository: Geal/nom
Pull request #800 (2018-06-18 19:54:30)

Prevent fold_many1!() from turning a Failure into an Error.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/17555821/badge)](https://coveralls.io/builds/17555821)

Coverage decreased (-0.02%) to 87.542% when pulling **55af6ceea766c2211aa28bfc9bab0bef8de828ef on ProgVal:many1-failure** into **64af2d1cac7298b511eb671163dcdbb2ad197d17 on Geal:master**.


Patch:
diff --git a/Cargo.toml b/Cargo.toml
index 7712935..7f5afe1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -45,6 +45,10 @@ default-features = false
 #git = "https://github.com/carllerche/bytes"
 #rev = "a7d38e29"
 
+[package.metadata.docs.rs]
+features = [ "alloc", "std", "regexp", "regexp_macros", "verbose-errors" ]
+all-features = true
+
 [[test]]
 name = "arithmetic"
 
diff --git a/doc/home.md b/doc/home.md
index aba6163..179a96d 100644
--- a/doc/home.md
+++ b/doc/home.md
@@ -8,7 +8,7 @@ To get started using nom, you can include it in your Rust projects from
 * [Reference documentation](http://rust.unhandledexpression.com/nom/)
 * [Gitter chat room](https://gitter.im/Geal/nom). You can also go to the #nom IRC
 channel on irc.mozilla.org, or ping 'geal' on Mozilla, Freenode, Geeknode or oftc IRC
-* [Tutorial about parsing ISO8601 dates](https://fnordig.de/2015/07/16/omnomnom-parsing-iso8601-dates-using-nom/)
+* [Tutorial about parsing ISO8601 dates](https://github.com/badboy/iso8601/blob/338b3d1a9ca220372292f631a3bc2e5176cca331/docs/parsing-iso8601-dates-using-nom.md)
 * [Making a new parser from scratch](making_a_new_parser_from_scratch.html)
 (general tips on writing a parser and code architecture)
 * [How to handle parser errors](error_management.html)
diff --git a/doc/how_nom_macros_work.md b/doc/how_nom_macros_work.md
index 578f63f..5f5c97f 100644
--- a/doc/how_nom_macros_work.md
+++ b/doc/how_nom_macros_work.md
@@ -140,7 +140,7 @@ transformed with the second pattern:
 opt!(call!(digit))
 ```
 
-The `call!` macro transforms `call!(input, f)` into `f(i)`. If you need to pass more parameters to the function, you can Use `call!(input, f, arg, arg2)` to get `f(i, arg, arg2)`.
+The `call!` macro transforms `call!(input, f)` into `f(input)`. If you need to pass more parameters to the function, you can Use `call!(input, f, arg, arg2)` to get `f(input, arg, arg2)`.
 
 ## Using the macro's parameters
 
diff --git a/doc/making_a_new_parser_from_scratch.md b/doc/making_a_new_parser_from_scratch.md
index e1b43fe..c6b2f92 100644
--- a/doc/making_a_new_parser_from_scratch.md
+++ b/doc/making_a_new_parser_from_scratch.md
@@ -251,7 +251,7 @@ This particular one is caused by `named!` generating a function returning a `IRe
 
 There are a few tools you can use to debug how code is generated.
 
-## trace_macros
+## trace\_macros
 
 The `trace_macros` feature show how macros are applied. To use it, add `#![feature(trace_macros)]` at the top of your file (you need Rust nightly for this), then apply it like this:
 
diff --git a/doc/upgrading_to_nom_2.md b/doc/upgrading_to_nom_2.md
index 0eb2abc..b60b908 100644
--- a/doc/upgrading_to_nom_2.md
+++ b/doc/upgrading_to_nom_2.md
@@ -106,7 +106,7 @@ you can fix it with:
 +    c == 0x0
 ```
 
-## length_value, length_bytes refactoring
+## `length_value!`, `length_bytes!` refactoring
 
 The "length-value" pattern usually indicates that we get a length from the input, then take a slice of that size from the input, and convert that to a value of the type we need. The `length_value!` macro was using the length parameter to apply the value parser a specific number of times.
 
@@ -133,7 +133,7 @@ error[E0308]: mismatched types
          sig_hash_algs_len: be_u16 ~
 ```
 
-## error! does not exist anymore
+## `error!` does not exist anymore
 
 The `error!` macro, that was used to return a parsing error without backtracking through the parser tree, is now called `return_error!`. This change was done because the "log" crate also uses an `error!` macro, and they complained about the name conflict to nom instead of complaining to log, much to my dismay.
 
diff --git a/doc/upgrading_to_nom_4.md b/doc/upgrading_to_nom_4.md
index a28c4bd..76c2b13 100644
--- a/doc/upgrading_to_nom_4.md
+++ b/doc/upgrading_to_nom_4.md
@@ -231,10 +231,7 @@ If those types feel a bit long to write everywhere in the parsers, it's possible
 to alias them like this:
 
 ```rust,ignore
-type Input<'a> = CompleteByteSlice<'a>;
-pub fn Input<'a>(input:&'a[u8]) -> Input<'a> {
-  CompleteByteSlice(input)
-}
+use nom::types::CompleteByteSlice as Input;
 ```
 
 ## Custom error types
diff --git a/src/bits.rs b/src/bits.rs
index f0c3e77..ffb7531 100644
--- a/src/bits.rs
+++ b/src/bits.rs
@@ -159,7 +159,7 @@ macro_rules! bytes_impl (
   ($macro_i:expr, $submac:ident!( $($args:tt)* )) => (
     {
       use $crate::lib::std::result::Result::*;
-      use $crate::{Err,Needed};
+      use $crate::{Err,Needed,Context};
 
       let inp;
       if $macro_i.1 % 8 != 0 {
@@ -219,7 +219,7 @@ macro_rules! bytes_impl (
   ($macro_i:expr, $submac:ident!( $($args:tt)* )) => (
     {
       use $crate::lib::std::result::Result::*;
-      use $crate::{Err,Needed};
+      use $crate::{Err,Needed,Context};
 
       let inp;
       if $macro_i.1 % 8 != 0 {
diff --git a/src/bytes.rs b/src/bytes.rs
index ea37ffd..d5c0a47 100644
--- a/src/bytes.rs
+++ b/src/bytes.rs
@@ -300,6 +300,7 @@ macro_rules! escaped_transform (
       use $crate::ExtendInto;
       use $crate::InputIter;
       use $crate::InputLength;
+      use $crate::Needed;
       use $crate::Slice;
       use $crate::need_more;
 
@@ -759,7 +760,7 @@ macro_rules! take_until_and_consume1 (
 /// consumes data until it finds the specified tag.
 ///
 /// The remainder still contains the tag.
-/// (As opposed to `take_until!` which removes it from the remainder.)
+/// (As opposed to `take_until_and_consume!` which removes it from the remainder.)
 ///
 /// # Example
 /// ```
diff --git a/src/lib.rs b/src/lib.rs
index 8d391be..908eab6 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -166,7 +166,7 @@
 //! It can have the following values:
 //!
 //! - a correct result `Ok((I,O))` with the first element being the remaining of the input (not parsed yet), and the second the output value;
-//! - an error `Err(Err::Error(c))` with `c` an enum that contians an error code with its position in the input, and optionally a chain of accumulated errors;
+//! - an error `Err(Err::Error(c))` with `c` an enum that contains an error code with its position in the input, and optionally a chain of accumulated errors;
 //! - an error `Err(Err::Incomplete(Needed))` indicating that more input is necessary. `Needed` can indicate how much data is needed
 //! - an error `Err(Err::Failure(c))`. It works like the `Error` case, except it indicates an unrecoverable error: we cannot backtrack and test another parser
 //!
diff --git a/src/macros.rs b/src/macros.rs
index c1e571f..7c1ec3a 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -150,6 +150,33 @@ macro_rules! named (
 );
 
 /// 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]
 macro_rules! named_args {
     (pub $func_name:ident ( $( $arg:ident : $typ:ty ),* ) < $return_type:ty > , $submac:ident!( $($args:tt)* ) ) => {
@@ -950,7 +977,6 @@ macro_rules! cond_with_error(
   ($i:expr, $cond:expr, $submac:ident!( $($args:tt)* )) => (
     {
       use $crate::lib::std::result::Result::*;
-      use $crate::{Convert,Err,Needed,IResult};
 
       if $cond {
         match $submac!($i, $($args)*) {
diff --git a/src/multi.rs b/src/multi.rs
index c6aed73..d77936d 100644
--- a/src/multi.rs
+++ b/src/multi.rs
@@ -926,7 +926,7 @@ macro_rules! fold_many1(
           }
 
           match failure {
-            $crate::lib::std::option::Option::Some(e) => Err(Err::Error(e)),
+            $crate::lib::std::option::Option::Some(e) => Err(Err::Failure(e)),
             $crate::lib::std::option::Option::None    => match incomplete {
               $crate::lib::std::option::Option::Some(i) => $crate::need_more($i, i),
               $crate::lib::std::option::Option::None    => Ok((input, acc))
diff --git a/src/nom.rs b/src/nom.rs
index 3f28dbe..c6d9867 100644
--- a/src/nom.rs
+++ b/src/nom.rs
@@ -584,28 +584,28 @@ pub enum Endianness {
 /// if the parameter is nom::Endianness::Big, parse a big endian u16 integer,
 /// otherwise a little endian u16 integer
 #[macro_export]
-macro_rules! u16 ( ($i:expr, $e:expr) => ( {if $crate::Endianness::Big == $e { be_u16($i) } else { le_u16($i) } } ););
+macro_rules! u16 ( ($i:expr, $e:expr) => ( {if $crate::Endianness::Big == $e { $crate::be_u16($i) } else { $crate::le_u16($i) } } ););
 /// if the parameter is nom::Endianness::Big, parse a big endian u32 integer,
 /// otherwise a little endian u32 integer
 #[macro_export]
-macro_rules! u32 ( ($i:expr, $e:expr) => ( {if $crate::Endianness::Big == $e { be_u32($i) } else { le_u32($i) } } ););
+macro_rules! u32 ( ($i:expr, $e:expr) => ( {if $crate::Endianness::Big == $e { $crate::be_u32($i) } else { $crate::le_u32($i) } } ););
 /// if the parameter is nom::Endianness::Big, parse a big endian u64 integer,
 /// otherwise a little endian u64 integer
 #[macro_export]
-macro_rules! u64 ( ($i:expr, $e:expr) => ( {if $crate::Endianness::Big == $e { be_u64($i) } else { le_u64($i) } } ););
+macro_rules! u64 ( ($i:expr, $e:expr) => ( {if $crate::Endianness::Big == $e { $crate::be_u64($i) } else { $crate::le_u64($i) } } ););
 
 /// if the parameter is nom::Endianness::Big, parse a big endian i16 integer,
 /// otherwise a little endian i16 integer
 #[macro_export]
-macro_rules! i16 ( ($i:expr, $e:expr) => ( {if $crate::Endianness::Big == $e { be_i16($i) } else { le_i16($i) } } ););
+macro_rules! i16 ( ($i:expr, $e:expr) => ( {if $crate::Endianness::Big == $e { $crate::be_i16($i) } else { $crate::le_i16($i) } } ););
 /// if the parameter is nom::Endianness::Big, parse a big endian i32 integer,
 /// otherwise a little endian i32 integer
 #[macro_export]
-macro_rules! i32 ( ($i:expr, $e:expr) => ( {if $crate::Endianness::Big == $e { be_i32($i) } else { le_i32($i) } } ););
+macro_rules! i32 ( ($i:expr, $e:expr) => ( {if $crate::Endianness::Big == $e { $crate::be_i32($i) } else { $crate::le_i32($i) } } ););
 /// if the parameter is nom::Endianness::Big, parse a big endian i64 integer,
 /// otherwise a little endian i64 integer
 #[macro_export]
-macro_rules! i64 ( ($i:expr, $e:expr) => ( {if $crate::Endianness::Big == $e { be_i64($i) } else { le_i64($i) } } ););
+macro_rules! i64 ( ($i:expr, $e:expr) => ( {if $crate::Endianness::Big == $e { $crate::be_i64($i) } else { $crate::le_i64($i) } } ););
 
 /// Recognizes big endian 4 bytes floating point number
 #[inline]


Test patch:
diff --git a/tests/issues.rs b/tests/issues.rs
index 66d3753..8d4115e 100644
--- a/tests/issues.rs
+++ b/tests/issues.rs
@@ -272,3 +272,12 @@ fn issue_759() {
 named_args!(issue_771(count: usize)<Vec<u32>>,
   length_count!(value!(count), call!(nom::be_u32))
 );
+
+/// This test is in a separate module to check that all required symbols are imported in
+/// `escaped_transform!()`. Without the module, the `use`-es of the current module would
+/// mask the error ('"Use of undeclared type or module `Needed`" in escaped_transform!').
+mod issue_780 {
+  named!(issue_780<&str, String>,
+    escaped_transform!(call!(::nom::alpha), '\\', tag!("n"))
+  );
+}