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