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