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