nom/character/
streaming.rs

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