• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Character specific parsers and combinators, streaming version
2 //!
3 //! Functions recognizing specific characters
4 
5 use crate::branch::alt;
6 use crate::combinator::opt;
7 use crate::error::ErrorKind;
8 use crate::error::ParseError;
9 use crate::internal::{Err, IResult, Needed};
10 use crate::lib::std::ops::{Range, RangeFrom, RangeTo};
11 use crate::traits::{
12   AsChar, FindToken, InputIter, InputLength, InputTake, InputTakeAtPosition, Slice,
13 };
14 use crate::traits::{Compare, CompareResult};
15 
16 /// Recognizes one character.
17 ///
18 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
19 /// # Example
20 ///
21 /// ```
22 /// # use nom::{Err, error::{ErrorKind, Error}, Needed, IResult};
23 /// # use nom::character::streaming::char;
24 /// fn parser(i: &str) -> IResult<&str, char> {
25 ///     char('a')(i)
26 /// }
27 /// assert_eq!(parser("abc"), Ok(("bc", 'a')));
28 /// assert_eq!(parser("bc"), Err(Err::Error(Error::new("bc", ErrorKind::Char))));
29 /// assert_eq!(parser(""), Err(Err::Incomplete(Needed::new(1))));
30 /// ```
char<I, Error: ParseError<I>>(c: char) -> impl Fn(I) -> IResult<I, char, Error> where I: Slice<RangeFrom<usize>> + InputIter + InputLength, <I as InputIter>::Item: AsChar,31 pub fn char<I, Error: ParseError<I>>(c: char) -> impl Fn(I) -> IResult<I, char, Error>
32 where
33   I: Slice<RangeFrom<usize>> + InputIter + InputLength,
34   <I as InputIter>::Item: AsChar,
35 {
36   move |i: I| match (i).iter_elements().next().map(|t| {
37     let b = t.as_char() == c;
38     (&c, b)
39   }) {
40     None => Err(Err::Incomplete(Needed::new(c.len() - i.input_len()))),
41     Some((_, false)) => Err(Err::Error(Error::from_char(i, c))),
42     Some((c, true)) => Ok((i.slice(c.len()..), c.as_char())),
43   }
44 }
45 
46 /// Recognizes one character and checks that it satisfies a predicate
47 ///
48 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
49 /// # Example
50 ///
51 /// ```
52 /// # use nom::{Err, error::{ErrorKind, Error}, Needed, IResult};
53 /// # use nom::character::streaming::satisfy;
54 /// fn parser(i: &str) -> IResult<&str, char> {
55 ///     satisfy(|c| c == 'a' || c == 'b')(i)
56 /// }
57 /// assert_eq!(parser("abc"), Ok(("bc", 'a')));
58 /// assert_eq!(parser("cd"), Err(Err::Error(Error::new("cd", ErrorKind::Satisfy))));
59 /// assert_eq!(parser(""), Err(Err::Incomplete(Needed::Unknown)));
60 /// ```
satisfy<F, I, Error: ParseError<I>>(cond: F) -> impl Fn(I) -> IResult<I, char, Error> where I: Slice<RangeFrom<usize>> + InputIter, <I as InputIter>::Item: AsChar, F: Fn(char) -> bool,61 pub fn satisfy<F, I, Error: ParseError<I>>(cond: F) -> impl Fn(I) -> IResult<I, char, Error>
62 where
63   I: Slice<RangeFrom<usize>> + InputIter,
64   <I as InputIter>::Item: AsChar,
65   F: Fn(char) -> bool,
66 {
67   move |i: I| match (i).iter_elements().next().map(|t| {
68     let c = t.as_char();
69     let b = cond(c);
70     (c, b)
71   }) {
72     None => Err(Err::Incomplete(Needed::Unknown)),
73     Some((_, false)) => Err(Err::Error(Error::from_error_kind(i, ErrorKind::Satisfy))),
74     Some((c, true)) => Ok((i.slice(c.len()..), c)),
75   }
76 }
77 
78 /// Recognizes one of the provided characters.
79 ///
80 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
81 /// # Example
82 ///
83 /// ```
84 /// # use nom::{Err, error::ErrorKind, Needed};
85 /// # use nom::character::streaming::one_of;
86 /// assert_eq!(one_of::<_, _, (_, ErrorKind)>("abc")("b"), Ok(("", 'b')));
87 /// assert_eq!(one_of::<_, _, (_, ErrorKind)>("a")("bc"), Err(Err::Error(("bc", ErrorKind::OneOf))));
88 /// assert_eq!(one_of::<_, _, (_, ErrorKind)>("a")(""), Err(Err::Incomplete(Needed::new(1))));
89 /// ```
one_of<I, T, Error: ParseError<I>>(list: T) -> impl Fn(I) -> IResult<I, char, Error> where I: Slice<RangeFrom<usize>> + InputIter, <I as InputIter>::Item: AsChar + Copy, T: FindToken<<I as InputIter>::Item>,90 pub fn one_of<I, T, Error: ParseError<I>>(list: T) -> impl Fn(I) -> IResult<I, char, Error>
91 where
92   I: Slice<RangeFrom<usize>> + InputIter,
93   <I as InputIter>::Item: AsChar + Copy,
94   T: FindToken<<I as InputIter>::Item>,
95 {
96   move |i: I| match (i).iter_elements().next().map(|c| (c, list.find_token(c))) {
97     None => Err(Err::Incomplete(Needed::new(1))),
98     Some((_, false)) => Err(Err::Error(Error::from_error_kind(i, ErrorKind::OneOf))),
99     Some((c, true)) => Ok((i.slice(c.len()..), c.as_char())),
100   }
101 }
102 
103 /// Recognizes a character that is not in the provided characters.
104 ///
105 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
106 /// # Example
107 ///
108 /// ```
109 /// # use nom::{Err, error::ErrorKind, Needed};
110 /// # use nom::character::streaming::none_of;
111 /// assert_eq!(none_of::<_, _, (_, ErrorKind)>("abc")("z"), Ok(("", 'z')));
112 /// assert_eq!(none_of::<_, _, (_, ErrorKind)>("ab")("a"), Err(Err::Error(("a", ErrorKind::NoneOf))));
113 /// assert_eq!(none_of::<_, _, (_, ErrorKind)>("a")(""), Err(Err::Incomplete(Needed::new(1))));
114 /// ```
none_of<I, T, Error: ParseError<I>>(list: T) -> impl Fn(I) -> IResult<I, char, Error> where I: Slice<RangeFrom<usize>> + InputIter, <I as InputIter>::Item: AsChar + Copy, T: FindToken<<I as InputIter>::Item>,115 pub fn none_of<I, T, Error: ParseError<I>>(list: T) -> impl Fn(I) -> IResult<I, char, Error>
116 where
117   I: Slice<RangeFrom<usize>> + InputIter,
118   <I as InputIter>::Item: AsChar + Copy,
119   T: FindToken<<I as InputIter>::Item>,
120 {
121   move |i: I| match (i).iter_elements().next().map(|c| (c, !list.find_token(c))) {
122     None => Err(Err::Incomplete(Needed::new(1))),
123     Some((_, false)) => Err(Err::Error(Error::from_error_kind(i, ErrorKind::NoneOf))),
124     Some((c, true)) => Ok((i.slice(c.len()..), c.as_char())),
125   }
126 }
127 
128 /// Recognizes the string "\r\n".
129 ///
130 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
131 /// # Example
132 ///
133 /// ```
134 /// # use nom::{Err, error::ErrorKind, IResult, Needed};
135 /// # use nom::character::streaming::crlf;
136 /// assert_eq!(crlf::<_, (_, ErrorKind)>("\r\nc"), Ok(("c", "\r\n")));
137 /// assert_eq!(crlf::<_, (_, ErrorKind)>("ab\r\nc"), Err(Err::Error(("ab\r\nc", ErrorKind::CrLf))));
138 /// assert_eq!(crlf::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(2))));
139 /// ```
crlf<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> where T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>, T: InputIter, T: Compare<&'static str>,140 pub fn crlf<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
141 where
142   T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
143   T: InputIter,
144   T: Compare<&'static str>,
145 {
146   match input.compare("\r\n") {
147     //FIXME: is this the right index?
148     CompareResult::Ok => Ok((input.slice(2..), input.slice(0..2))),
149     CompareResult::Incomplete => Err(Err::Incomplete(Needed::new(2))),
150     CompareResult::Error => {
151       let e: ErrorKind = ErrorKind::CrLf;
152       Err(Err::Error(E::from_error_kind(input, e)))
153     }
154   }
155 }
156 
157 /// Recognizes a string of any char except '\r\n' or '\n'.
158 ///
159 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
160 /// # Example
161 ///
162 /// ```
163 /// # use nom::{Err, error::{Error, ErrorKind}, IResult, Needed};
164 /// # use nom::character::streaming::not_line_ending;
165 /// assert_eq!(not_line_ending::<_, (_, ErrorKind)>("ab\r\nc"), Ok(("\r\nc", "ab")));
166 /// assert_eq!(not_line_ending::<_, (_, ErrorKind)>("abc"), Err(Err::Incomplete(Needed::Unknown)));
167 /// assert_eq!(not_line_ending::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::Unknown)));
168 /// assert_eq!(not_line_ending::<_, (_, ErrorKind)>("a\rb\nc"), Err(Err::Error(("a\rb\nc", ErrorKind::Tag ))));
169 /// assert_eq!(not_line_ending::<_, (_, ErrorKind)>("a\rbc"), Err(Err::Error(("a\rbc", ErrorKind::Tag ))));
170 /// ```
not_line_ending<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> where T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>, T: InputIter + InputLength, T: Compare<&'static str>, <T as InputIter>::Item: AsChar, <T as InputIter>::Item: AsChar,171 pub fn not_line_ending<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
172 where
173   T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
174   T: InputIter + InputLength,
175   T: Compare<&'static str>,
176   <T as InputIter>::Item: AsChar,
177   <T as InputIter>::Item: AsChar,
178 {
179   match input.position(|item| {
180     let c = item.as_char();
181     c == '\r' || c == '\n'
182   }) {
183     None => Err(Err::Incomplete(Needed::Unknown)),
184     Some(index) => {
185       let mut it = input.slice(index..).iter_elements();
186       let nth = it.next().unwrap().as_char();
187       if nth == '\r' {
188         let sliced = input.slice(index..);
189         let comp = sliced.compare("\r\n");
190         match comp {
191           //FIXME: calculate the right index
192           CompareResult::Incomplete => Err(Err::Incomplete(Needed::Unknown)),
193           CompareResult::Error => {
194             let e: ErrorKind = ErrorKind::Tag;
195             Err(Err::Error(E::from_error_kind(input, e)))
196           }
197           CompareResult::Ok => Ok((input.slice(index..), input.slice(..index))),
198         }
199       } else {
200         Ok((input.slice(index..), input.slice(..index)))
201       }
202     }
203   }
204 }
205 
206 /// Recognizes an end of line (both '\n' and '\r\n').
207 ///
208 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
209 /// # Example
210 ///
211 /// ```
212 /// # use nom::{Err, error::ErrorKind, IResult, Needed};
213 /// # use nom::character::streaming::line_ending;
214 /// assert_eq!(line_ending::<_, (_, ErrorKind)>("\r\nc"), Ok(("c", "\r\n")));
215 /// assert_eq!(line_ending::<_, (_, ErrorKind)>("ab\r\nc"), Err(Err::Error(("ab\r\nc", ErrorKind::CrLf))));
216 /// assert_eq!(line_ending::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
217 /// ```
line_ending<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> where T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>, T: InputIter + InputLength, T: Compare<&'static str>,218 pub fn line_ending<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
219 where
220   T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
221   T: InputIter + InputLength,
222   T: Compare<&'static str>,
223 {
224   match input.compare("\n") {
225     CompareResult::Ok => Ok((input.slice(1..), input.slice(0..1))),
226     CompareResult::Incomplete => Err(Err::Incomplete(Needed::new(1))),
227     CompareResult::Error => {
228       match input.compare("\r\n") {
229         //FIXME: is this the right index?
230         CompareResult::Ok => Ok((input.slice(2..), input.slice(0..2))),
231         CompareResult::Incomplete => Err(Err::Incomplete(Needed::new(2))),
232         CompareResult::Error => Err(Err::Error(E::from_error_kind(input, ErrorKind::CrLf))),
233       }
234     }
235   }
236 }
237 
238 /// Matches a newline character '\\n'.
239 ///
240 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
241 /// # Example
242 ///
243 /// ```
244 /// # use nom::{Err, error::ErrorKind, IResult, Needed};
245 /// # use nom::character::streaming::newline;
246 /// assert_eq!(newline::<_, (_, ErrorKind)>("\nc"), Ok(("c", '\n')));
247 /// assert_eq!(newline::<_, (_, ErrorKind)>("\r\nc"), Err(Err::Error(("\r\nc", ErrorKind::Char))));
248 /// assert_eq!(newline::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
249 /// ```
newline<I, Error: ParseError<I>>(input: I) -> IResult<I, char, Error> where I: Slice<RangeFrom<usize>> + InputIter + InputLength, <I as InputIter>::Item: AsChar,250 pub fn newline<I, Error: ParseError<I>>(input: I) -> IResult<I, char, Error>
251 where
252   I: Slice<RangeFrom<usize>> + InputIter + InputLength,
253   <I as InputIter>::Item: AsChar,
254 {
255   char('\n')(input)
256 }
257 
258 /// Matches a tab character '\t'.
259 ///
260 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
261 /// # Example
262 ///
263 /// ```
264 /// # use nom::{Err, error::ErrorKind, IResult, Needed};
265 /// # use nom::character::streaming::tab;
266 /// assert_eq!(tab::<_, (_, ErrorKind)>("\tc"), Ok(("c", '\t')));
267 /// assert_eq!(tab::<_, (_, ErrorKind)>("\r\nc"), Err(Err::Error(("\r\nc", ErrorKind::Char))));
268 /// assert_eq!(tab::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
269 /// ```
tab<I, Error: ParseError<I>>(input: I) -> IResult<I, char, Error> where I: Slice<RangeFrom<usize>> + InputIter + InputLength, <I as InputIter>::Item: AsChar,270 pub fn tab<I, Error: ParseError<I>>(input: I) -> IResult<I, char, Error>
271 where
272   I: Slice<RangeFrom<usize>> + InputIter + InputLength,
273   <I as InputIter>::Item: AsChar,
274 {
275   char('\t')(input)
276 }
277 
278 /// Matches one byte as a character. Note that the input type will
279 /// accept a `str`, but not a `&[u8]`, unlike many other nom parsers.
280 ///
281 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
282 /// # Example
283 ///
284 /// ```
285 /// # use nom::{character::streaming::anychar, Err, error::ErrorKind, IResult, Needed};
286 /// assert_eq!(anychar::<_, (_, ErrorKind)>("abc"), Ok(("bc",'a')));
287 /// assert_eq!(anychar::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
288 /// ```
anychar<T, E: ParseError<T>>(input: T) -> IResult<T, char, E> where T: InputIter + InputLength + Slice<RangeFrom<usize>>, <T as InputIter>::Item: AsChar,289 pub fn anychar<T, E: ParseError<T>>(input: T) -> IResult<T, char, E>
290 where
291   T: InputIter + InputLength + Slice<RangeFrom<usize>>,
292   <T as InputIter>::Item: AsChar,
293 {
294   let mut it = input.iter_indices();
295   match it.next() {
296     None => Err(Err::Incomplete(Needed::new(1))),
297     Some((_, c)) => match it.next() {
298       None => Ok((input.slice(input.input_len()..), c.as_char())),
299       Some((idx, _)) => Ok((input.slice(idx..), c.as_char())),
300     },
301   }
302 }
303 
304 /// Recognizes zero or more lowercase and uppercase ASCII alphabetic characters: a-z, A-Z
305 ///
306 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
307 /// or if no terminating token is found (a non alphabetic character).
308 /// # Example
309 ///
310 /// ```
311 /// # use nom::{Err, error::ErrorKind, IResult, Needed};
312 /// # use nom::character::streaming::alpha0;
313 /// assert_eq!(alpha0::<_, (_, ErrorKind)>("ab1c"), Ok(("1c", "ab")));
314 /// assert_eq!(alpha0::<_, (_, ErrorKind)>("1c"), Ok(("1c", "")));
315 /// assert_eq!(alpha0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
316 /// ```
alpha0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> where T: InputTakeAtPosition, <T as InputTakeAtPosition>::Item: AsChar,317 pub fn alpha0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
318 where
319   T: InputTakeAtPosition,
320   <T as InputTakeAtPosition>::Item: AsChar,
321 {
322   input.split_at_position(|item| !item.is_alpha())
323 }
324 
325 /// Recognizes one or more lowercase and uppercase ASCII alphabetic characters: a-z, A-Z
326 ///
327 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
328 /// or if no terminating token is found (a non alphabetic character).
329 /// # Example
330 ///
331 /// ```
332 /// # use nom::{Err, error::ErrorKind, IResult, Needed};
333 /// # use nom::character::streaming::alpha1;
334 /// assert_eq!(alpha1::<_, (_, ErrorKind)>("aB1c"), Ok(("1c", "aB")));
335 /// assert_eq!(alpha1::<_, (_, ErrorKind)>("1c"), Err(Err::Error(("1c", ErrorKind::Alpha))));
336 /// assert_eq!(alpha1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
337 /// ```
alpha1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> where T: InputTakeAtPosition, <T as InputTakeAtPosition>::Item: AsChar,338 pub fn alpha1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
339 where
340   T: InputTakeAtPosition,
341   <T as InputTakeAtPosition>::Item: AsChar,
342 {
343   input.split_at_position1(|item| !item.is_alpha(), ErrorKind::Alpha)
344 }
345 
346 /// Recognizes zero or more ASCII numerical characters: 0-9
347 ///
348 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
349 /// or if no terminating token is found (a non digit character).
350 /// # Example
351 ///
352 /// ```
353 /// # use nom::{Err, error::ErrorKind, IResult, Needed};
354 /// # use nom::character::streaming::digit0;
355 /// assert_eq!(digit0::<_, (_, ErrorKind)>("21c"), Ok(("c", "21")));
356 /// assert_eq!(digit0::<_, (_, ErrorKind)>("a21c"), Ok(("a21c", "")));
357 /// assert_eq!(digit0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
358 /// ```
digit0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> where T: InputTakeAtPosition, <T as InputTakeAtPosition>::Item: AsChar,359 pub fn digit0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
360 where
361   T: InputTakeAtPosition,
362   <T as InputTakeAtPosition>::Item: AsChar,
363 {
364   input.split_at_position(|item| !item.is_dec_digit())
365 }
366 
367 /// Recognizes one or more ASCII numerical characters: 0-9
368 ///
369 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
370 /// or if no terminating token is found (a non digit character).
371 /// # Example
372 ///
373 /// ```
374 /// # use nom::{Err, error::ErrorKind, IResult, Needed};
375 /// # use nom::character::streaming::digit1;
376 /// assert_eq!(digit1::<_, (_, ErrorKind)>("21c"), Ok(("c", "21")));
377 /// assert_eq!(digit1::<_, (_, ErrorKind)>("c1"), Err(Err::Error(("c1", ErrorKind::Digit))));
378 /// assert_eq!(digit1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
379 /// ```
digit1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> where T: InputTakeAtPosition, <T as InputTakeAtPosition>::Item: AsChar,380 pub fn digit1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
381 where
382   T: InputTakeAtPosition,
383   <T as InputTakeAtPosition>::Item: AsChar,
384 {
385   input.split_at_position1(|item| !item.is_dec_digit(), ErrorKind::Digit)
386 }
387 
388 /// Recognizes zero or more ASCII hexadecimal numerical characters: 0-9, A-F, a-f
389 ///
390 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
391 /// or if no terminating token is found (a non hexadecimal digit character).
392 /// # Example
393 ///
394 /// ```
395 /// # use nom::{Err, error::ErrorKind, IResult, Needed};
396 /// # use nom::character::streaming::hex_digit0;
397 /// assert_eq!(hex_digit0::<_, (_, ErrorKind)>("21cZ"), Ok(("Z", "21c")));
398 /// assert_eq!(hex_digit0::<_, (_, ErrorKind)>("Z21c"), Ok(("Z21c", "")));
399 /// assert_eq!(hex_digit0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
400 /// ```
hex_digit0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> where T: InputTakeAtPosition, <T as InputTakeAtPosition>::Item: AsChar,401 pub fn hex_digit0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
402 where
403   T: InputTakeAtPosition,
404   <T as InputTakeAtPosition>::Item: AsChar,
405 {
406   input.split_at_position(|item| !item.is_hex_digit())
407 }
408 
409 /// Recognizes one or more ASCII hexadecimal numerical characters: 0-9, A-F, a-f
410 ///
411 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
412 /// or if no terminating token is found (a non hexadecimal digit character).
413 /// # Example
414 ///
415 /// ```
416 /// # use nom::{Err, error::ErrorKind, IResult, Needed};
417 /// # use nom::character::streaming::hex_digit1;
418 /// assert_eq!(hex_digit1::<_, (_, ErrorKind)>("21cZ"), Ok(("Z", "21c")));
419 /// assert_eq!(hex_digit1::<_, (_, ErrorKind)>("H2"), Err(Err::Error(("H2", ErrorKind::HexDigit))));
420 /// assert_eq!(hex_digit1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
421 /// ```
hex_digit1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> where T: InputTakeAtPosition, <T as InputTakeAtPosition>::Item: AsChar,422 pub fn hex_digit1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
423 where
424   T: InputTakeAtPosition,
425   <T as InputTakeAtPosition>::Item: AsChar,
426 {
427   input.split_at_position1(|item| !item.is_hex_digit(), ErrorKind::HexDigit)
428 }
429 
430 /// Recognizes zero or more octal characters: 0-7
431 ///
432 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
433 /// or if no terminating token is found (a non octal digit character).
434 /// # Example
435 ///
436 /// ```
437 /// # use nom::{Err, error::ErrorKind, IResult, Needed};
438 /// # use nom::character::streaming::oct_digit0;
439 /// assert_eq!(oct_digit0::<_, (_, ErrorKind)>("21cZ"), Ok(("cZ", "21")));
440 /// assert_eq!(oct_digit0::<_, (_, ErrorKind)>("Z21c"), Ok(("Z21c", "")));
441 /// assert_eq!(oct_digit0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
442 /// ```
oct_digit0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> where T: InputTakeAtPosition, <T as InputTakeAtPosition>::Item: AsChar,443 pub fn oct_digit0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
444 where
445   T: InputTakeAtPosition,
446   <T as InputTakeAtPosition>::Item: AsChar,
447 {
448   input.split_at_position(|item| !item.is_oct_digit())
449 }
450 
451 /// Recognizes one or more octal characters: 0-7
452 ///
453 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
454 /// or if no terminating token is found (a non octal digit character).
455 /// # Example
456 ///
457 /// ```
458 /// # use nom::{Err, error::ErrorKind, IResult, Needed};
459 /// # use nom::character::streaming::oct_digit1;
460 /// assert_eq!(oct_digit1::<_, (_, ErrorKind)>("21cZ"), Ok(("cZ", "21")));
461 /// assert_eq!(oct_digit1::<_, (_, ErrorKind)>("H2"), Err(Err::Error(("H2", ErrorKind::OctDigit))));
462 /// assert_eq!(oct_digit1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
463 /// ```
oct_digit1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> where T: InputTakeAtPosition, <T as InputTakeAtPosition>::Item: AsChar,464 pub fn oct_digit1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
465 where
466   T: InputTakeAtPosition,
467   <T as InputTakeAtPosition>::Item: AsChar,
468 {
469   input.split_at_position1(|item| !item.is_oct_digit(), ErrorKind::OctDigit)
470 }
471 
472 /// Recognizes zero or more ASCII numerical and alphabetic characters: 0-9, a-z, A-Z
473 ///
474 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
475 /// or if no terminating token is found (a non alphanumerical character).
476 /// # Example
477 ///
478 /// ```
479 /// # use nom::{Err, error::ErrorKind, IResult, Needed};
480 /// # use nom::character::streaming::alphanumeric0;
481 /// assert_eq!(alphanumeric0::<_, (_, ErrorKind)>("21cZ%1"), Ok(("%1", "21cZ")));
482 /// assert_eq!(alphanumeric0::<_, (_, ErrorKind)>("&Z21c"), Ok(("&Z21c", "")));
483 /// assert_eq!(alphanumeric0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
484 /// ```
alphanumeric0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> where T: InputTakeAtPosition, <T as InputTakeAtPosition>::Item: AsChar,485 pub fn alphanumeric0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
486 where
487   T: InputTakeAtPosition,
488   <T as InputTakeAtPosition>::Item: AsChar,
489 {
490   input.split_at_position(|item| !item.is_alphanum())
491 }
492 
493 /// Recognizes one or more ASCII numerical and alphabetic characters: 0-9, a-z, A-Z
494 ///
495 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
496 /// or if no terminating token is found (a non alphanumerical character).
497 /// # Example
498 ///
499 /// ```
500 /// # use nom::{Err, error::ErrorKind, IResult, Needed};
501 /// # use nom::character::streaming::alphanumeric1;
502 /// assert_eq!(alphanumeric1::<_, (_, ErrorKind)>("21cZ%1"), Ok(("%1", "21cZ")));
503 /// assert_eq!(alphanumeric1::<_, (_, ErrorKind)>("&H2"), Err(Err::Error(("&H2", ErrorKind::AlphaNumeric))));
504 /// assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
505 /// ```
alphanumeric1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> where T: InputTakeAtPosition, <T as InputTakeAtPosition>::Item: AsChar,506 pub fn alphanumeric1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
507 where
508   T: InputTakeAtPosition,
509   <T as InputTakeAtPosition>::Item: AsChar,
510 {
511   input.split_at_position1(|item| !item.is_alphanum(), ErrorKind::AlphaNumeric)
512 }
513 
514 /// Recognizes zero or more spaces and tabs.
515 ///
516 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
517 /// or if no terminating token is found (a non space character).
518 /// # Example
519 ///
520 /// ```
521 /// # use nom::{Err, error::ErrorKind, IResult, Needed};
522 /// # use nom::character::streaming::space0;
523 /// assert_eq!(space0::<_, (_, ErrorKind)>(" \t21c"), Ok(("21c", " \t")));
524 /// assert_eq!(space0::<_, (_, ErrorKind)>("Z21c"), Ok(("Z21c", "")));
525 /// assert_eq!(space0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
526 /// ```
space0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> where T: InputTakeAtPosition, <T as InputTakeAtPosition>::Item: AsChar + Clone,527 pub fn space0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
528 where
529   T: InputTakeAtPosition,
530   <T as InputTakeAtPosition>::Item: AsChar + Clone,
531 {
532   input.split_at_position(|item| {
533     let c = item.as_char();
534     !(c == ' ' || c == '\t')
535   })
536 }
537 /// Recognizes one or more spaces and tabs.
538 ///
539 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
540 /// or if no terminating token is found (a non space character).
541 /// # Example
542 ///
543 /// ```
544 /// # use nom::{Err, error::ErrorKind, IResult, Needed};
545 /// # use nom::character::streaming::space1;
546 /// assert_eq!(space1::<_, (_, ErrorKind)>(" \t21c"), Ok(("21c", " \t")));
547 /// assert_eq!(space1::<_, (_, ErrorKind)>("H2"), Err(Err::Error(("H2", ErrorKind::Space))));
548 /// assert_eq!(space1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
549 /// ```
space1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> where T: InputTakeAtPosition, <T as InputTakeAtPosition>::Item: AsChar + Clone,550 pub fn space1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
551 where
552   T: InputTakeAtPosition,
553   <T as InputTakeAtPosition>::Item: AsChar + Clone,
554 {
555   input.split_at_position1(
556     |item| {
557       let c = item.as_char();
558       !(c == ' ' || c == '\t')
559     },
560     ErrorKind::Space,
561   )
562 }
563 
564 /// Recognizes zero or more spaces, tabs, carriage returns and line feeds.
565 ///
566 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
567 /// or if no terminating token is found (a non space character).
568 /// # Example
569 ///
570 /// ```
571 /// # use nom::{Err, error::ErrorKind, IResult, Needed};
572 /// # use nom::character::streaming::multispace0;
573 /// assert_eq!(multispace0::<_, (_, ErrorKind)>(" \t\n\r21c"), Ok(("21c", " \t\n\r")));
574 /// assert_eq!(multispace0::<_, (_, ErrorKind)>("Z21c"), Ok(("Z21c", "")));
575 /// assert_eq!(multispace0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
576 /// ```
multispace0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> where T: InputTakeAtPosition, <T as InputTakeAtPosition>::Item: AsChar + Clone,577 pub fn multispace0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
578 where
579   T: InputTakeAtPosition,
580   <T as InputTakeAtPosition>::Item: AsChar + Clone,
581 {
582   input.split_at_position(|item| {
583     let c = item.as_char();
584     !(c == ' ' || c == '\t' || c == '\r' || c == '\n')
585   })
586 }
587 
588 /// Recognizes one or more spaces, tabs, carriage returns and line feeds.
589 ///
590 /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
591 /// or if no terminating token is found (a non space character).
592 /// # Example
593 ///
594 /// ```
595 /// # use nom::{Err, error::ErrorKind, IResult, Needed};
596 /// # use nom::character::streaming::multispace1;
597 /// assert_eq!(multispace1::<_, (_, ErrorKind)>(" \t\n\r21c"), Ok(("21c", " \t\n\r")));
598 /// assert_eq!(multispace1::<_, (_, ErrorKind)>("H2"), Err(Err::Error(("H2", ErrorKind::MultiSpace))));
599 /// assert_eq!(multispace1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
600 /// ```
multispace1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E> where T: InputTakeAtPosition, <T as InputTakeAtPosition>::Item: AsChar + Clone,601 pub fn multispace1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
602 where
603   T: InputTakeAtPosition,
604   <T as InputTakeAtPosition>::Item: AsChar + Clone,
605 {
606   input.split_at_position1(
607     |item| {
608       let c = item.as_char();
609       !(c == ' ' || c == '\t' || c == '\r' || c == '\n')
610     },
611     ErrorKind::MultiSpace,
612   )
613 }
614 
sign<T, E: ParseError<T>>(input: T) -> IResult<T, bool, E> where T: Clone + InputTake + InputLength, T: for<'a> Compare<&'a [u8]>,615 pub(crate) fn sign<T, E: ParseError<T>>(input: T) -> IResult<T, bool, E>
616 where
617   T: Clone + InputTake + InputLength,
618   T: for<'a> Compare<&'a [u8]>,
619 {
620   use crate::bytes::streaming::tag;
621   use crate::combinator::value;
622 
623   let (i, opt_sign) = opt(alt((
624     value(false, tag(&b"-"[..])),
625     value(true, tag(&b"+"[..])),
626   )))(input)?;
627   let sign = opt_sign.unwrap_or(true);
628 
629   Ok((i, sign))
630 }
631 
632 #[doc(hidden)]
633 macro_rules! ints {
634     ($($t:tt)+) => {
635         $(
636         /// will parse a number in text form to a number
637         ///
638         /// *Complete version*: can parse until the end of input.
639         pub fn $t<T, E: ParseError<T>>(input: T) -> IResult<T, $t, E>
640             where
641             T: InputIter + Slice<RangeFrom<usize>> + InputLength + InputTake + Clone,
642             <T as InputIter>::Item: AsChar,
643             T: for <'a> Compare<&'a[u8]>,
644             {
645               let (i, sign) = sign(input.clone())?;
646 
647                 if i.input_len() == 0 {
648                     return Err(Err::Incomplete(Needed::new(1)));
649                 }
650 
651                 let mut value: $t = 0;
652                 if sign {
653                     for (pos, c) in i.iter_indices() {
654                         match c.as_char().to_digit(10) {
655                             None => {
656                                 if pos == 0 {
657                                     return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit)));
658                                 } else {
659                                     return Ok((i.slice(pos..), value));
660                                 }
661                             },
662                             Some(d) => match value.checked_mul(10).and_then(|v| v.checked_add(d as $t)) {
663                                 None => return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit))),
664                                 Some(v) => value = v,
665                             }
666                         }
667                     }
668                 } else {
669                     for (pos, c) in i.iter_indices() {
670                         match c.as_char().to_digit(10) {
671                             None => {
672                                 if pos == 0 {
673                                     return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit)));
674                                 } else {
675                                     return Ok((i.slice(pos..), value));
676                                 }
677                             },
678                             Some(d) => match value.checked_mul(10).and_then(|v| v.checked_sub(d as $t)) {
679                                 None => return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit))),
680                                 Some(v) => value = v,
681                             }
682                         }
683                     }
684                 }
685 
686                 Err(Err::Incomplete(Needed::new(1)))
687             }
688         )+
689     }
690 }
691 
692 ints! { i8 i16 i32 i64 i128 }
693 
694 #[doc(hidden)]
695 macro_rules! uints {
696     ($($t:tt)+) => {
697         $(
698         /// will parse a number in text form to a number
699         ///
700         /// *Complete version*: can parse until the end of input.
701         pub fn $t<T, E: ParseError<T>>(input: T) -> IResult<T, $t, E>
702             where
703             T: InputIter + Slice<RangeFrom<usize>> + InputLength,
704             <T as InputIter>::Item: AsChar,
705             {
706                 let i = input;
707 
708                 if i.input_len() == 0 {
709                     return Err(Err::Incomplete(Needed::new(1)));
710                 }
711 
712                 let mut value: $t = 0;
713                 for (pos, c) in i.iter_indices() {
714                     match c.as_char().to_digit(10) {
715                         None => {
716                             if pos == 0 {
717                                 return Err(Err::Error(E::from_error_kind(i, ErrorKind::Digit)));
718                             } else {
719                                 return Ok((i.slice(pos..), value));
720                             }
721                         },
722                         Some(d) => match value.checked_mul(10).and_then(|v| v.checked_add(d as $t)) {
723                             None => return Err(Err::Error(E::from_error_kind(i, ErrorKind::Digit))),
724                             Some(v) => value = v,
725                         }
726                     }
727                 }
728 
729                 Err(Err::Incomplete(Needed::new(1)))
730             }
731         )+
732     }
733 }
734 
735 uints! { u8 u16 u32 u64 u128 }
736 
737 #[cfg(test)]
738 mod tests {
739   use super::*;
740   use crate::error::ErrorKind;
741   use crate::internal::{Err, Needed};
742   use crate::sequence::pair;
743   use crate::traits::ParseTo;
744   use proptest::prelude::*;
745 
746   macro_rules! assert_parse(
747     ($left: expr, $right: expr) => {
748       let res: $crate::IResult<_, _, (_, ErrorKind)> = $left;
749       assert_eq!(res, $right);
750     };
751   );
752 
753   #[test]
anychar_str()754   fn anychar_str() {
755     use super::anychar;
756     assert_eq!(anychar::<_, (&str, ErrorKind)>("Ә"), Ok(("", 'Ә')));
757   }
758 
759   #[test]
character()760   fn character() {
761     let a: &[u8] = b"abcd";
762     let b: &[u8] = b"1234";
763     let c: &[u8] = b"a123";
764     let d: &[u8] = "azé12".as_bytes();
765     let e: &[u8] = b" ";
766     let f: &[u8] = b" ;";
767     //assert_eq!(alpha1::<_, (_, ErrorKind)>(a), Err(Err::Incomplete(Needed::new(1))));
768     assert_parse!(alpha1(a), Err(Err::Incomplete(Needed::new(1))));
769     assert_eq!(alpha1(b), Err(Err::Error((b, ErrorKind::Alpha))));
770     assert_eq!(alpha1::<_, (_, ErrorKind)>(c), Ok((&c[1..], &b"a"[..])));
771     assert_eq!(
772       alpha1::<_, (_, ErrorKind)>(d),
773       Ok(("é12".as_bytes(), &b"az"[..]))
774     );
775     assert_eq!(digit1(a), Err(Err::Error((a, ErrorKind::Digit))));
776     assert_eq!(
777       digit1::<_, (_, ErrorKind)>(b),
778       Err(Err::Incomplete(Needed::new(1)))
779     );
780     assert_eq!(digit1(c), Err(Err::Error((c, ErrorKind::Digit))));
781     assert_eq!(digit1(d), Err(Err::Error((d, ErrorKind::Digit))));
782     assert_eq!(
783       hex_digit1::<_, (_, ErrorKind)>(a),
784       Err(Err::Incomplete(Needed::new(1)))
785     );
786     assert_eq!(
787       hex_digit1::<_, (_, ErrorKind)>(b),
788       Err(Err::Incomplete(Needed::new(1)))
789     );
790     assert_eq!(
791       hex_digit1::<_, (_, ErrorKind)>(c),
792       Err(Err::Incomplete(Needed::new(1)))
793     );
794     assert_eq!(
795       hex_digit1::<_, (_, ErrorKind)>(d),
796       Ok(("zé12".as_bytes(), &b"a"[..]))
797     );
798     assert_eq!(hex_digit1(e), Err(Err::Error((e, ErrorKind::HexDigit))));
799     assert_eq!(oct_digit1(a), Err(Err::Error((a, ErrorKind::OctDigit))));
800     assert_eq!(
801       oct_digit1::<_, (_, ErrorKind)>(b),
802       Err(Err::Incomplete(Needed::new(1)))
803     );
804     assert_eq!(oct_digit1(c), Err(Err::Error((c, ErrorKind::OctDigit))));
805     assert_eq!(oct_digit1(d), Err(Err::Error((d, ErrorKind::OctDigit))));
806     assert_eq!(
807       alphanumeric1::<_, (_, ErrorKind)>(a),
808       Err(Err::Incomplete(Needed::new(1)))
809     );
810     //assert_eq!(fix_error!(b,(), alphanumeric1), Ok((empty, b)));
811     assert_eq!(
812       alphanumeric1::<_, (_, ErrorKind)>(c),
813       Err(Err::Incomplete(Needed::new(1)))
814     );
815     assert_eq!(
816       alphanumeric1::<_, (_, ErrorKind)>(d),
817       Ok(("é12".as_bytes(), &b"az"[..]))
818     );
819     assert_eq!(
820       space1::<_, (_, ErrorKind)>(e),
821       Err(Err::Incomplete(Needed::new(1)))
822     );
823     assert_eq!(space1::<_, (_, ErrorKind)>(f), Ok((&b";"[..], &b" "[..])));
824   }
825 
826   #[cfg(feature = "alloc")]
827   #[test]
character_s()828   fn character_s() {
829     let a = "abcd";
830     let b = "1234";
831     let c = "a123";
832     let d = "azé12";
833     let e = " ";
834     assert_eq!(
835       alpha1::<_, (_, ErrorKind)>(a),
836       Err(Err::Incomplete(Needed::new(1)))
837     );
838     assert_eq!(alpha1(b), Err(Err::Error((b, ErrorKind::Alpha))));
839     assert_eq!(alpha1::<_, (_, ErrorKind)>(c), Ok((&c[1..], &"a"[..])));
840     assert_eq!(alpha1::<_, (_, ErrorKind)>(d), Ok(("é12", &"az"[..])));
841     assert_eq!(digit1(a), Err(Err::Error((a, ErrorKind::Digit))));
842     assert_eq!(
843       digit1::<_, (_, ErrorKind)>(b),
844       Err(Err::Incomplete(Needed::new(1)))
845     );
846     assert_eq!(digit1(c), Err(Err::Error((c, ErrorKind::Digit))));
847     assert_eq!(digit1(d), Err(Err::Error((d, ErrorKind::Digit))));
848     assert_eq!(
849       hex_digit1::<_, (_, ErrorKind)>(a),
850       Err(Err::Incomplete(Needed::new(1)))
851     );
852     assert_eq!(
853       hex_digit1::<_, (_, ErrorKind)>(b),
854       Err(Err::Incomplete(Needed::new(1)))
855     );
856     assert_eq!(
857       hex_digit1::<_, (_, ErrorKind)>(c),
858       Err(Err::Incomplete(Needed::new(1)))
859     );
860     assert_eq!(hex_digit1::<_, (_, ErrorKind)>(d), Ok(("zé12", &"a"[..])));
861     assert_eq!(hex_digit1(e), Err(Err::Error((e, ErrorKind::HexDigit))));
862     assert_eq!(oct_digit1(a), Err(Err::Error((a, ErrorKind::OctDigit))));
863     assert_eq!(
864       oct_digit1::<_, (_, ErrorKind)>(b),
865       Err(Err::Incomplete(Needed::new(1)))
866     );
867     assert_eq!(oct_digit1(c), Err(Err::Error((c, ErrorKind::OctDigit))));
868     assert_eq!(oct_digit1(d), Err(Err::Error((d, ErrorKind::OctDigit))));
869     assert_eq!(
870       alphanumeric1::<_, (_, ErrorKind)>(a),
871       Err(Err::Incomplete(Needed::new(1)))
872     );
873     //assert_eq!(fix_error!(b,(), alphanumeric1), Ok((empty, b)));
874     assert_eq!(
875       alphanumeric1::<_, (_, ErrorKind)>(c),
876       Err(Err::Incomplete(Needed::new(1)))
877     );
878     assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(d), Ok(("é12", "az")));
879     assert_eq!(
880       space1::<_, (_, ErrorKind)>(e),
881       Err(Err::Incomplete(Needed::new(1)))
882     );
883   }
884 
885   use crate::traits::Offset;
886   #[test]
offset()887   fn offset() {
888     let a = &b"abcd;"[..];
889     let b = &b"1234;"[..];
890     let c = &b"a123;"[..];
891     let d = &b" \t;"[..];
892     let e = &b" \t\r\n;"[..];
893     let f = &b"123abcDEF;"[..];
894 
895     match alpha1::<_, (_, ErrorKind)>(a) {
896       Ok((i, _)) => {
897         assert_eq!(a.offset(i) + i.len(), a.len());
898       }
899       _ => panic!("wrong return type in offset test for alpha"),
900     }
901     match digit1::<_, (_, ErrorKind)>(b) {
902       Ok((i, _)) => {
903         assert_eq!(b.offset(i) + i.len(), b.len());
904       }
905       _ => panic!("wrong return type in offset test for digit"),
906     }
907     match alphanumeric1::<_, (_, ErrorKind)>(c) {
908       Ok((i, _)) => {
909         assert_eq!(c.offset(i) + i.len(), c.len());
910       }
911       _ => panic!("wrong return type in offset test for alphanumeric"),
912     }
913     match space1::<_, (_, ErrorKind)>(d) {
914       Ok((i, _)) => {
915         assert_eq!(d.offset(i) + i.len(), d.len());
916       }
917       _ => panic!("wrong return type in offset test for space"),
918     }
919     match multispace1::<_, (_, ErrorKind)>(e) {
920       Ok((i, _)) => {
921         assert_eq!(e.offset(i) + i.len(), e.len());
922       }
923       _ => panic!("wrong return type in offset test for multispace"),
924     }
925     match hex_digit1::<_, (_, ErrorKind)>(f) {
926       Ok((i, _)) => {
927         assert_eq!(f.offset(i) + i.len(), f.len());
928       }
929       _ => panic!("wrong return type in offset test for hex_digit"),
930     }
931     match oct_digit1::<_, (_, ErrorKind)>(f) {
932       Ok((i, _)) => {
933         assert_eq!(f.offset(i) + i.len(), f.len());
934       }
935       _ => panic!("wrong return type in offset test for oct_digit"),
936     }
937   }
938 
939   #[test]
is_not_line_ending_bytes()940   fn is_not_line_ending_bytes() {
941     let a: &[u8] = b"ab12cd\nefgh";
942     assert_eq!(
943       not_line_ending::<_, (_, ErrorKind)>(a),
944       Ok((&b"\nefgh"[..], &b"ab12cd"[..]))
945     );
946 
947     let b: &[u8] = b"ab12cd\nefgh\nijkl";
948     assert_eq!(
949       not_line_ending::<_, (_, ErrorKind)>(b),
950       Ok((&b"\nefgh\nijkl"[..], &b"ab12cd"[..]))
951     );
952 
953     let c: &[u8] = b"ab12cd\r\nefgh\nijkl";
954     assert_eq!(
955       not_line_ending::<_, (_, ErrorKind)>(c),
956       Ok((&b"\r\nefgh\nijkl"[..], &b"ab12cd"[..]))
957     );
958 
959     let d: &[u8] = b"ab12cd";
960     assert_eq!(
961       not_line_ending::<_, (_, ErrorKind)>(d),
962       Err(Err::Incomplete(Needed::Unknown))
963     );
964   }
965 
966   #[test]
is_not_line_ending_str()967   fn is_not_line_ending_str() {
968     /*
969     let a: &str = "ab12cd\nefgh";
970     assert_eq!(not_line_ending(a), Ok((&"\nefgh"[..], &"ab12cd"[..])));
971 
972     let b: &str = "ab12cd\nefgh\nijkl";
973     assert_eq!(not_line_ending(b), Ok((&"\nefgh\nijkl"[..], &"ab12cd"[..])));
974 
975     let c: &str = "ab12cd\r\nefgh\nijkl";
976     assert_eq!(not_line_ending(c), Ok((&"\r\nefgh\nijkl"[..], &"ab12cd"[..])));
977 
978     let d = "βèƒôřè\nÂßÇáƒƭèř";
979     assert_eq!(not_line_ending(d), Ok((&"\nÂßÇáƒƭèř"[..], &"βèƒôřè"[..])));
980 
981     let e = "βèƒôřè\r\nÂßÇáƒƭèř";
982     assert_eq!(not_line_ending(e), Ok((&"\r\nÂßÇáƒƭèř"[..], &"βèƒôřè"[..])));
983     */
984 
985     let f = "βèƒôřè\rÂßÇáƒƭèř";
986     assert_eq!(not_line_ending(f), Err(Err::Error((f, ErrorKind::Tag))));
987 
988     let g2: &str = "ab12cd";
989     assert_eq!(
990       not_line_ending::<_, (_, ErrorKind)>(g2),
991       Err(Err::Incomplete(Needed::Unknown))
992     );
993   }
994 
995   #[test]
hex_digit_test()996   fn hex_digit_test() {
997     let i = &b"0123456789abcdefABCDEF;"[..];
998     assert_parse!(hex_digit1(i), Ok((&b";"[..], &i[..i.len() - 1])));
999 
1000     let i = &b"g"[..];
1001     assert_parse!(
1002       hex_digit1(i),
1003       Err(Err::Error(error_position!(i, ErrorKind::HexDigit)))
1004     );
1005 
1006     let i = &b"G"[..];
1007     assert_parse!(
1008       hex_digit1(i),
1009       Err(Err::Error(error_position!(i, ErrorKind::HexDigit)))
1010     );
1011 
1012     assert!(crate::character::is_hex_digit(b'0'));
1013     assert!(crate::character::is_hex_digit(b'9'));
1014     assert!(crate::character::is_hex_digit(b'a'));
1015     assert!(crate::character::is_hex_digit(b'f'));
1016     assert!(crate::character::is_hex_digit(b'A'));
1017     assert!(crate::character::is_hex_digit(b'F'));
1018     assert!(!crate::character::is_hex_digit(b'g'));
1019     assert!(!crate::character::is_hex_digit(b'G'));
1020     assert!(!crate::character::is_hex_digit(b'/'));
1021     assert!(!crate::character::is_hex_digit(b':'));
1022     assert!(!crate::character::is_hex_digit(b'@'));
1023     assert!(!crate::character::is_hex_digit(b'\x60'));
1024   }
1025 
1026   #[test]
oct_digit_test()1027   fn oct_digit_test() {
1028     let i = &b"01234567;"[..];
1029     assert_parse!(oct_digit1(i), Ok((&b";"[..], &i[..i.len() - 1])));
1030 
1031     let i = &b"8"[..];
1032     assert_parse!(
1033       oct_digit1(i),
1034       Err(Err::Error(error_position!(i, ErrorKind::OctDigit)))
1035     );
1036 
1037     assert!(crate::character::is_oct_digit(b'0'));
1038     assert!(crate::character::is_oct_digit(b'7'));
1039     assert!(!crate::character::is_oct_digit(b'8'));
1040     assert!(!crate::character::is_oct_digit(b'9'));
1041     assert!(!crate::character::is_oct_digit(b'a'));
1042     assert!(!crate::character::is_oct_digit(b'A'));
1043     assert!(!crate::character::is_oct_digit(b'/'));
1044     assert!(!crate::character::is_oct_digit(b':'));
1045     assert!(!crate::character::is_oct_digit(b'@'));
1046     assert!(!crate::character::is_oct_digit(b'\x60'));
1047   }
1048 
1049   #[test]
full_line_windows()1050   fn full_line_windows() {
1051     fn take_full_line(i: &[u8]) -> IResult<&[u8], (&[u8], &[u8])> {
1052       pair(not_line_ending, line_ending)(i)
1053     }
1054     let input = b"abc\r\n";
1055     let output = take_full_line(input);
1056     assert_eq!(output, Ok((&b""[..], (&b"abc"[..], &b"\r\n"[..]))));
1057   }
1058 
1059   #[test]
full_line_unix()1060   fn full_line_unix() {
1061     fn take_full_line(i: &[u8]) -> IResult<&[u8], (&[u8], &[u8])> {
1062       pair(not_line_ending, line_ending)(i)
1063     }
1064     let input = b"abc\n";
1065     let output = take_full_line(input);
1066     assert_eq!(output, Ok((&b""[..], (&b"abc"[..], &b"\n"[..]))));
1067   }
1068 
1069   #[test]
check_windows_lineending()1070   fn check_windows_lineending() {
1071     let input = b"\r\n";
1072     let output = line_ending(&input[..]);
1073     assert_parse!(output, Ok((&b""[..], &b"\r\n"[..])));
1074   }
1075 
1076   #[test]
check_unix_lineending()1077   fn check_unix_lineending() {
1078     let input = b"\n";
1079     let output = line_ending(&input[..]);
1080     assert_parse!(output, Ok((&b""[..], &b"\n"[..])));
1081   }
1082 
1083   #[test]
cr_lf()1084   fn cr_lf() {
1085     assert_parse!(crlf(&b"\r\na"[..]), Ok((&b"a"[..], &b"\r\n"[..])));
1086     assert_parse!(crlf(&b"\r"[..]), Err(Err::Incomplete(Needed::new(2))));
1087     assert_parse!(
1088       crlf(&b"\ra"[..]),
1089       Err(Err::Error(error_position!(&b"\ra"[..], ErrorKind::CrLf)))
1090     );
1091 
1092     assert_parse!(crlf("\r\na"), Ok(("a", "\r\n")));
1093     assert_parse!(crlf("\r"), Err(Err::Incomplete(Needed::new(2))));
1094     assert_parse!(
1095       crlf("\ra"),
1096       Err(Err::Error(error_position!("\ra", ErrorKind::CrLf)))
1097     );
1098   }
1099 
1100   #[test]
end_of_line()1101   fn end_of_line() {
1102     assert_parse!(line_ending(&b"\na"[..]), Ok((&b"a"[..], &b"\n"[..])));
1103     assert_parse!(line_ending(&b"\r\na"[..]), Ok((&b"a"[..], &b"\r\n"[..])));
1104     assert_parse!(
1105       line_ending(&b"\r"[..]),
1106       Err(Err::Incomplete(Needed::new(2)))
1107     );
1108     assert_parse!(
1109       line_ending(&b"\ra"[..]),
1110       Err(Err::Error(error_position!(&b"\ra"[..], ErrorKind::CrLf)))
1111     );
1112 
1113     assert_parse!(line_ending("\na"), Ok(("a", "\n")));
1114     assert_parse!(line_ending("\r\na"), Ok(("a", "\r\n")));
1115     assert_parse!(line_ending("\r"), Err(Err::Incomplete(Needed::new(2))));
1116     assert_parse!(
1117       line_ending("\ra"),
1118       Err(Err::Error(error_position!("\ra", ErrorKind::CrLf)))
1119     );
1120   }
1121 
digit_to_i16(input: &str) -> IResult<&str, i16>1122   fn digit_to_i16(input: &str) -> IResult<&str, i16> {
1123     let i = input;
1124     let (i, opt_sign) = opt(alt((char('+'), char('-'))))(i)?;
1125     let sign = match opt_sign {
1126       Some('+') => true,
1127       Some('-') => false,
1128       _ => true,
1129     };
1130 
1131     let (i, s) = match digit1::<_, crate::error::Error<_>>(i) {
1132       Ok((i, s)) => (i, s),
1133       Err(Err::Incomplete(i)) => return Err(Err::Incomplete(i)),
1134       Err(_) => {
1135         return Err(Err::Error(crate::error::Error::from_error_kind(
1136           input,
1137           ErrorKind::Digit,
1138         )))
1139       }
1140     };
1141     match s.parse_to() {
1142       Some(n) => {
1143         if sign {
1144           Ok((i, n))
1145         } else {
1146           Ok((i, -n))
1147         }
1148       }
1149       None => Err(Err::Error(crate::error::Error::from_error_kind(
1150         i,
1151         ErrorKind::Digit,
1152       ))),
1153     }
1154   }
1155 
digit_to_u32(i: &str) -> IResult<&str, u32>1156   fn digit_to_u32(i: &str) -> IResult<&str, u32> {
1157     let (i, s) = digit1(i)?;
1158     match s.parse_to() {
1159       Some(n) => Ok((i, n)),
1160       None => Err(Err::Error(crate::error::Error::from_error_kind(
1161         i,
1162         ErrorKind::Digit,
1163       ))),
1164     }
1165   }
1166 
1167   proptest! {
1168     #[test]
1169     fn ints(s in "\\PC*") {
1170         let res1 = digit_to_i16(&s);
1171         let res2 = i16(s.as_str());
1172         assert_eq!(res1, res2);
1173     }
1174 
1175     #[test]
1176     fn uints(s in "\\PC*") {
1177         let res1 = digit_to_u32(&s);
1178         let res2 = u32(s.as_str());
1179         assert_eq!(res1, res2);
1180     }
1181   }
1182 }
1183