nom/character/
complete.rs

1//! Character specific parsers and combinators, complete input version.
2//!
3//! Functions recognizing specific characters.
4
5use crate::branch::alt;
6use crate::combinator::opt;
7use crate::error::ErrorKind;
8use crate::error::ParseError;
9use crate::internal::{Err, IResult};
10use crate::lib::std::ops::{Range, RangeFrom, RangeTo};
11use crate::traits::{
12  AsChar, FindToken, InputIter, InputLength, InputTake, InputTakeAtPosition, Slice,
13};
14use 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/// ```
32pub fn char<I, Error: ParseError<I>>(c: char) -> impl Fn(I) -> IResult<I, char, Error>
33where
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/// ```
61pub fn satisfy<F, I, Error: ParseError<I>>(cond: F) -> impl Fn(I) -> IResult<I, char, Error>
62where
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/// ```
89pub fn one_of<I, T, Error: ParseError<I>>(list: T) -> impl Fn(I) -> IResult<I, char, Error>
90where
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/// ```
113pub fn none_of<I, T, Error: ParseError<I>>(list: T) -> impl Fn(I) -> IResult<I, char, Error>
114where
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/// ```
141pub fn crlf<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
142where
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/// ```
177pub fn not_line_ending<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
178where
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/// ```
227pub fn line_ending<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
228where
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/// ```
262pub fn newline<I, Error: ParseError<I>>(input: I) -> IResult<I, char, Error>
263where
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/// ```
286pub fn tab<I, Error: ParseError<I>>(input: I) -> IResult<I, char, Error>
287where
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/// ```
309pub fn anychar<T, E: ParseError<T>>(input: T) -> IResult<T, char, E>
310where
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/// ```
341pub fn alpha0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
342where
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/// ```
366pub fn alpha1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
367where
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/// ```
392pub fn digit0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
393where
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
435pub fn digit1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
436where
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/// ```
459pub fn hex_digit0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
460where
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/// ```
483pub fn hex_digit1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
484where
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/// ```
508pub fn oct_digit0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
509where
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/// ```
533pub fn oct_digit1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
534where
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/// ```
558pub fn alphanumeric0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
559where
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/// ```
583pub fn alphanumeric1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
584where
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/// ```
608pub fn space0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
609where
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/// ```
636pub fn space1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
637where
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/// ```
667pub fn multispace0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
668where
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/// ```
695pub fn multispace1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
696where
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
709pub(crate) fn sign<T, E: ParseError<T>>(input: T) -> IResult<T, bool, E>
710where
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)]
727macro_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
786ints! { i8 i16 i32 i64 i128 }
787
788#[doc(hidden)]
789macro_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
829uints! { u8 u16 u32 u64 u128 }
830
831#[cfg(test)]
832mod 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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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
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
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}