Repository: Geal/nom
Pull request #1004 (2019-07-24 01:19:37)

Fix custom_input_types.md
I tried to fix custom_input_types.md.
This PR includes two changes.

* Change the sample parser code to function-style of nom5.
* Separate the traits list into "for MyInput" and "for MyItem". I think `AsChar` is a trait for `Item` type.



Patch:
diff --git a/doc/custom_input_types.md b/doc/custom_input_types.md
index 1c6f725..aadf25b 100644
--- a/doc/custom_input_types.md
+++ b/doc/custom_input_types.md
@@ -10,21 +10,20 @@ that can carry line and column information, or to parse
 
 ## Implementing a custom type
 
-Let's assume we have an input type we'll call `MyInput`. The goal is to define
-nom parsers with this signature: `MyInput -> IResult<MyInput, Output>`.
-To employ it in a `named!` parser, you can write it like this:
+Let's assume we have an input type we'll call `MyInput`. `MyInput` is a sequence of `MyItem` type.
+The goal is to define nom parsers with this signature: `MyInput -> IResult<MyInput, Output>`.
 
 ```rust
-named!(parser<MyInput, Output>, tag!("test"));
+fn parser(i: MyInput) -> IResult<MyInput, Output> {
+    tag("test")(i)
+}
 ```
 
-Here are the traits we have to implement:
-
+Here are the traits we have to implement for `MyInput`:
 
 | trait | usage |
 |---|---|
 | [AsBytes](https://docs.rs/nom/latest/nom/trait.AsBytes.html) | casts the input type to a byte slice |
-| [AsChar](https://docs.rs/nom/latest/nom/trait.AsChar.html) | transforms common types to a char for basic token parsing |
 | [Compare](https://docs.rs/nom/latest/nom/trait.Compare.html) | character comparison operations |
 | [ExtendInto](https://docs.rs/nom/latest/nom/trait.ExtendInto.html) |abstracts something which can extend an Extend |
 | [FindSubstring](https://docs.rs/nom/latest/nom/trait.FindSubstring.html) | look for a substring in self |
@@ -36,3 +35,9 @@ Here are the traits we have to implement:
 | [Offset](https://docs.rs/nom/latest/nom/trait.Offset.html) | calculate the offset between slices |
 | [ParseTo](https://docs.rs/nom/latest/nom/trait.ParseTo.html) | used to integrate `&str`'s parse() method |
 | [Slice](https://docs.rs/nom/latest/nom/trait.Slice.html) | slicing operations using ranges |
+
+Here are the traits we have to implement for `MyItem`:
+
+| trait | usage |
+|---|---|
+| [AsChar](https://docs.rs/nom/latest/nom/trait.AsChar.html) | transforms common types to a char for basic token parsing |
diff --git a/src/combinator/macros.rs b/src/combinator/macros.rs
index aa164e2..ca80e2a 100644
--- a/src/combinator/macros.rs
+++ b/src/combinator/macros.rs
@@ -79,12 +79,12 @@
 /// # use nom::{named, tag};
 /// named!(my_function<&[u8], &[u8]>, tag!("abcd"));
 /// ```
-/// This one will have &[u8] as input type, &[u8] as output type:
+/// 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:
+/// Will use `&[u8]` as output type:
 /// ```
 /// # use nom::{named, tag};
 /// named!(my_function<&[u8]>, tag!("abcd"));
@@ -134,7 +134,7 @@ macro_rules! named (
 /// Makes a function from a parser combination with arguments.
 ///
 /// ```ignore
-/// //takes `&[u8]` as input
+/// //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))
 /// );
diff --git a/src/multi/mod.rs b/src/multi/mod.rs
index 269fc44..93b3e4c 100644
--- a/src/multi/mod.rs
+++ b/src/multi/mod.rs
@@ -409,6 +409,10 @@ where
     let mut input = i.clone();
     let mut count: usize = 0;
 
+    if n == 0 {
+        return Ok((i, vec!()))
+    }
+
     loop {
       let _i = input.clone();
       match f(_i) {


Test patch:
diff --git a/tests/issues.rs b/tests/issues.rs
index a7bf516..094b47c 100644
--- a/tests/issues.rs
+++ b/tests/issues.rs
@@ -290,3 +290,11 @@ fn issue_942() {
   }
   assert_eq!(parser::<()>("aaa"), Ok(("", 3)));
 }
+
+#[test]
+fn issue_many_m_n_with_zeros() {
+    use nom::multi::many_m_n;
+    use nom::character::complete::char;
+    let parser = many_m_n::<_, _, (), _>(0, 0, char('a'));
+    assert_eq!(parser("aaa"), Ok(("aaa", vec!())));
+}