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