Coverage Report

Created: 2021-11-03 07:11

/rust/registry/src/github.com-1ecc6299db9ec823/nom-5.1.2/src/character/streaming.rs
Line
Count
Source
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
/// ```
28
2.75M
pub fn char<I, Error: ParseError<I>>(c: char) -> impl Fn(I) -> IResult<I, char, Error>
29
2.75M
where
30
2.75M
  I: Slice<RangeFrom<usize>> + InputIter,
31
2.75M
  <I as InputIter>::Item: AsChar,
32
2.75M
{
33
2.75M
  move |i: I| match (i).iter_elements().next().map(|t| {
34
2.75M
    let b = t.as_char() == c;
35
2.75M
    (&c, b)
36
2.75M
  }) {
37
912
    None => Err(Err::Incomplete(Needed::Size(1))),
38
    Some((_, false)) => {
39
191k
      Err(Err::Error(Error::from_char(i, c)))
40
    }
41
2.56M
    Some((c, true)) => Ok((i.slice(c.len()..), c.as_char())),
42
2.75M
  }
43
2.75M
}
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
/// ```
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
/// ```
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
/// ```
116
3.18M
pub fn crlf<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
117
3.18M
where
118
3.18M
  T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
119
3.18M
  T: InputIter,
120
3.18M
  T: Compare<&'static str>,
121
3.18M
{
122
3.18M
  match input.compare("\r\n") {
123
    //FIXME: is this the right index?
124
2.35M
    CompareResult::Ok => Ok((input.slice(2..), input.slice(0..2))),
125
1.07k
    CompareResult::Incomplete => Err(Err::Incomplete(Needed::Size(2))),
126
    CompareResult::Error => {
127
826k
      let e: ErrorKind = ErrorKind::CrLf;
128
826k
      Err(Err::Error(E::from_error_kind(input, e)))
129
    }
130
  }
131
3.18M
}
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
/// ```
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
/// ```
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
/// ```
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
/// ```
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
/// ```
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
/// ```
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
/// ```
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
/// ```
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
/// ```
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
/// ```
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
/// ```
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
/// ```
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
/// ```
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
/// ```
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
/// ```
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
/// ```
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
/// ```
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
/// ```
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
/// ```
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]
662
  fn anychar_str() {
663
    use super::anychar;
664
    assert_eq!(anychar::<_, (&str, ErrorKind)>("Ә"), Ok(("", 'Ә')));
665
  }
666
667
  #[test]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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
}