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