Coverage Report

Created: 2026-01-10 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/nom-8.0.0/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::branch::alt;
6
use crate::combinator::opt;
7
use crate::error::ErrorKind;
8
use crate::error::ParseError;
9
use crate::internal::{Err, IResult, Needed};
10
use crate::traits::{AsChar, FindToken, Input};
11
use crate::traits::{Compare, CompareResult};
12
use crate::Emit;
13
use crate::OutputM;
14
use crate::Parser;
15
use crate::Streaming;
16
17
/// Recognizes one character.
18
///
19
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
20
/// # Example
21
///
22
/// ```
23
/// # use nom::{Err, error::{ErrorKind, Error}, Needed, IResult};
24
/// # use nom::character::streaming::char;
25
/// fn parser(i: &str) -> IResult<&str, char> {
26
///     char('a')(i)
27
/// }
28
/// assert_eq!(parser("abc"), Ok(("bc", 'a')));
29
/// assert_eq!(parser("bc"), Err(Err::Error(Error::new("bc", ErrorKind::Char))));
30
/// assert_eq!(parser(""), Err(Err::Incomplete(Needed::new(1))));
31
/// ```
32
0
pub fn char<I, Error: ParseError<I>>(c: char) -> impl FnMut(I) -> IResult<I, char, Error>
33
0
where
34
0
  I: Input,
35
0
  <I as Input>::Item: AsChar,
36
{
37
0
  let mut parser = super::char(c);
38
0
  move |i: I| parser.process::<OutputM<Emit, Emit, Streaming>>(i)
39
0
}
40
41
/// Recognizes one character and checks that it satisfies a predicate
42
///
43
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
44
/// # Example
45
///
46
/// ```
47
/// # use nom::{Err, error::{ErrorKind, Error}, Needed, IResult};
48
/// # use nom::character::streaming::satisfy;
49
/// fn parser(i: &str) -> IResult<&str, char> {
50
///     satisfy(|c| c == 'a' || c == 'b')(i)
51
/// }
52
/// assert_eq!(parser("abc"), Ok(("bc", 'a')));
53
/// assert_eq!(parser("cd"), Err(Err::Error(Error::new("cd", ErrorKind::Satisfy))));
54
/// assert_eq!(parser(""), Err(Err::Incomplete(Needed::Unknown)));
55
/// ```
56
0
pub fn satisfy<F, I, Error: ParseError<I>>(cond: F) -> impl FnMut(I) -> IResult<I, char, Error>
57
0
where
58
0
  I: Input,
59
0
  <I as Input>::Item: AsChar,
60
0
  F: Fn(char) -> bool,
61
{
62
0
  let mut parser = super::satisfy(cond);
63
0
  move |i: I| parser.process::<OutputM<Emit, Emit, Streaming>>(i)
64
0
}
65
66
/// Recognizes one of the provided characters.
67
///
68
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
69
/// # Example
70
///
71
/// ```
72
/// # use nom::{Err, error::ErrorKind, Needed};
73
/// # use nom::character::streaming::one_of;
74
/// assert_eq!(one_of::<_, _, (_, ErrorKind)>("abc")("b"), Ok(("", 'b')));
75
/// assert_eq!(one_of::<_, _, (_, ErrorKind)>("a")("bc"), Err(Err::Error(("bc", ErrorKind::OneOf))));
76
/// assert_eq!(one_of::<_, _, (_, ErrorKind)>("a")(""), Err(Err::Incomplete(Needed::Unknown)));
77
/// ```
78
0
pub fn one_of<I, T, Error: ParseError<I>>(list: T) -> impl FnMut(I) -> IResult<I, char, Error>
79
0
where
80
0
  I: Input,
81
0
  <I as Input>::Item: AsChar,
82
0
  T: FindToken<char>,
83
{
84
0
  let mut parser = super::one_of(list);
85
0
  move |i: I| parser.process::<OutputM<Emit, Emit, Streaming>>(i)
86
0
}
87
88
/// Recognizes a character that is not in the provided characters.
89
///
90
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
91
/// # Example
92
///
93
/// ```
94
/// # use nom::{Err, error::ErrorKind, Needed};
95
/// # use nom::character::streaming::none_of;
96
/// assert_eq!(none_of::<_, _, (_, ErrorKind)>("abc")("z"), Ok(("", 'z')));
97
/// assert_eq!(none_of::<_, _, (_, ErrorKind)>("ab")("a"), Err(Err::Error(("a", ErrorKind::NoneOf))));
98
/// assert_eq!(none_of::<_, _, (_, ErrorKind)>("a")(""), Err(Err::Incomplete(Needed::Unknown)));
99
/// ```
100
0
pub fn none_of<I, T, Error: ParseError<I>>(list: T) -> impl FnMut(I) -> IResult<I, char, Error>
101
0
where
102
0
  I: Input,
103
0
  <I as Input>::Item: AsChar,
104
0
  T: FindToken<char>,
105
{
106
0
  let mut parser = super::none_of(list);
107
0
  move |i: I| parser.process::<OutputM<Emit, Emit, Streaming>>(i)
108
0
}
109
110
/// Recognizes the string "\r\n".
111
///
112
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
113
/// # Example
114
///
115
/// ```
116
/// # use nom::{Err, error::ErrorKind, IResult, Needed};
117
/// # use nom::character::streaming::crlf;
118
/// assert_eq!(crlf::<_, (_, ErrorKind)>("\r\nc"), Ok(("c", "\r\n")));
119
/// assert_eq!(crlf::<_, (_, ErrorKind)>("ab\r\nc"), Err(Err::Error(("ab\r\nc", ErrorKind::CrLf))));
120
/// assert_eq!(crlf::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(2))));
121
/// ```
122
0
pub fn crlf<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
123
0
where
124
0
  T: Input,
125
0
  T: Compare<&'static str>,
126
{
127
0
  match input.compare("\r\n") {
128
    //FIXME: is this the right index?
129
0
    CompareResult::Ok => Ok(input.take_split(2)),
130
0
    CompareResult::Incomplete => Err(Err::Incomplete(Needed::new(2))),
131
    CompareResult::Error => {
132
0
      let e: ErrorKind = ErrorKind::CrLf;
133
0
      Err(Err::Error(E::from_error_kind(input, e)))
134
    }
135
  }
136
0
}
137
138
/// Recognizes a string of any char except '\r\n' or '\n'.
139
///
140
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
141
/// # Example
142
///
143
/// ```
144
/// # use nom::{Err, error::{Error, ErrorKind}, IResult, Needed};
145
/// # use nom::character::streaming::not_line_ending;
146
/// assert_eq!(not_line_ending::<_, (_, ErrorKind)>("ab\r\nc"), Ok(("\r\nc", "ab")));
147
/// assert_eq!(not_line_ending::<_, (_, ErrorKind)>("abc"), Err(Err::Incomplete(Needed::Unknown)));
148
/// assert_eq!(not_line_ending::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::Unknown)));
149
/// assert_eq!(not_line_ending::<_, (_, ErrorKind)>("a\rb\nc"), Err(Err::Error(("a\rb\nc", ErrorKind::Tag ))));
150
/// assert_eq!(not_line_ending::<_, (_, ErrorKind)>("a\rbc"), Err(Err::Error(("a\rbc", ErrorKind::Tag ))));
151
/// ```
152
0
pub fn not_line_ending<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
153
0
where
154
0
  T: Input,
155
0
  T: Compare<&'static str>,
156
0
  <T as Input>::Item: AsChar,
157
{
158
0
  match input.position(|item| {
159
0
    let c = item.as_char();
160
0
    c == '\r' || c == '\n'
161
0
  }) {
162
0
    None => Err(Err::Incomplete(Needed::Unknown)),
163
0
    Some(index) => {
164
0
      let mut it = input.take_from(index).iter_elements();
165
0
      let nth = it.next().unwrap().as_char();
166
0
      if nth == '\r' {
167
0
        let sliced = input.take_from(index);
168
0
        let comp = sliced.compare("\r\n");
169
0
        match comp {
170
          //FIXME: calculate the right index
171
0
          CompareResult::Incomplete => Err(Err::Incomplete(Needed::Unknown)),
172
          CompareResult::Error => {
173
0
            let e: ErrorKind = ErrorKind::Tag;
174
0
            Err(Err::Error(E::from_error_kind(input, e)))
175
          }
176
0
          CompareResult::Ok => Ok(input.take_split(index)),
177
        }
178
      } else {
179
0
        Ok(input.take_split(index))
180
      }
181
    }
182
  }
183
0
}
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
/// # Example
189
///
190
/// ```
191
/// # use nom::{Err, error::ErrorKind, IResult, Needed};
192
/// # use nom::character::streaming::line_ending;
193
/// assert_eq!(line_ending::<_, (_, ErrorKind)>("\r\nc"), Ok(("c", "\r\n")));
194
/// assert_eq!(line_ending::<_, (_, ErrorKind)>("ab\r\nc"), Err(Err::Error(("ab\r\nc", ErrorKind::CrLf))));
195
/// assert_eq!(line_ending::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
196
/// ```
197
0
pub fn line_ending<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
198
0
where
199
0
  T: Input,
200
0
  T: Compare<&'static str>,
201
{
202
0
  match input.compare("\n") {
203
0
    CompareResult::Ok => Ok(input.take_split(1)),
204
0
    CompareResult::Incomplete => Err(Err::Incomplete(Needed::new(1))),
205
    CompareResult::Error => {
206
0
      match input.compare("\r\n") {
207
        //FIXME: is this the right index?
208
0
        CompareResult::Ok => Ok(input.take_split(2)),
209
0
        CompareResult::Incomplete => Err(Err::Incomplete(Needed::new(2))),
210
0
        CompareResult::Error => Err(Err::Error(E::from_error_kind(input, ErrorKind::CrLf))),
211
      }
212
    }
213
  }
214
0
}
215
216
/// Matches a newline character '\\n'.
217
///
218
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
219
/// # Example
220
///
221
/// ```
222
/// # use nom::{Err, error::ErrorKind, IResult, Needed};
223
/// # use nom::character::streaming::newline;
224
/// assert_eq!(newline::<_, (_, ErrorKind)>("\nc"), Ok(("c", '\n')));
225
/// assert_eq!(newline::<_, (_, ErrorKind)>("\r\nc"), Err(Err::Error(("\r\nc", ErrorKind::Char))));
226
/// assert_eq!(newline::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
227
/// ```
228
0
pub fn newline<I, Error: ParseError<I>>(input: I) -> IResult<I, char, Error>
229
0
where
230
0
  I: Input,
231
0
  <I as Input>::Item: AsChar,
232
{
233
0
  char('\n')(input)
234
0
}
235
236
/// Matches a tab character '\t'.
237
///
238
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
239
/// # Example
240
///
241
/// ```
242
/// # use nom::{Err, error::ErrorKind, IResult, Needed};
243
/// # use nom::character::streaming::tab;
244
/// assert_eq!(tab::<_, (_, ErrorKind)>("\tc"), Ok(("c", '\t')));
245
/// assert_eq!(tab::<_, (_, ErrorKind)>("\r\nc"), Err(Err::Error(("\r\nc", ErrorKind::Char))));
246
/// assert_eq!(tab::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
247
/// ```
248
0
pub fn tab<I, Error: ParseError<I>>(input: I) -> IResult<I, char, Error>
249
0
where
250
0
  I: Input,
251
0
  <I as Input>::Item: AsChar,
252
{
253
0
  char('\t')(input)
254
0
}
255
256
/// Matches one element as a character.
257
///
258
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
259
/// # Example
260
///
261
/// ```
262
/// # use nom::{character::streaming::anychar, Err, error::ErrorKind, IResult, Needed};
263
/// assert_eq!(anychar::<_, (_, ErrorKind)>("abc"), Ok(("bc",'a')));
264
/// assert_eq!(anychar::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
265
/// ```
266
0
pub fn anychar<T, E: ParseError<T>>(input: T) -> IResult<T, char, E>
267
0
where
268
0
  T: Input,
269
0
  <T as Input>::Item: AsChar,
270
{
271
0
  let mut it = input.iter_elements();
272
0
  match it.next() {
273
0
    None => Err(Err::Incomplete(Needed::new(1))),
274
0
    Some(c) => Ok((input.take_from(c.len()), c.as_char())),
275
  }
276
0
}
277
278
/// Recognizes zero or more lowercase and uppercase ASCII alphabetic characters: a-z, A-Z
279
///
280
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
281
/// or if no terminating token is found (a non alphabetic character).
282
/// # Example
283
///
284
/// ```
285
/// # use nom::{Err, error::ErrorKind, IResult, Needed};
286
/// # use nom::character::streaming::alpha0;
287
/// assert_eq!(alpha0::<_, (_, ErrorKind)>("ab1c"), Ok(("1c", "ab")));
288
/// assert_eq!(alpha0::<_, (_, ErrorKind)>("1c"), Ok(("1c", "")));
289
/// assert_eq!(alpha0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
290
/// ```
291
0
pub fn alpha0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
292
0
where
293
0
  T: Input,
294
0
  <T as Input>::Item: AsChar,
295
{
296
0
  input.split_at_position(|item| !item.is_alpha())
297
0
}
298
299
/// Recognizes one or more lowercase and uppercase ASCII alphabetic characters: a-z, A-Z
300
///
301
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
302
/// or if no terminating token is found (a non alphabetic character).
303
/// # Example
304
///
305
/// ```
306
/// # use nom::{Err, error::ErrorKind, IResult, Needed};
307
/// # use nom::character::streaming::alpha1;
308
/// assert_eq!(alpha1::<_, (_, ErrorKind)>("aB1c"), Ok(("1c", "aB")));
309
/// assert_eq!(alpha1::<_, (_, ErrorKind)>("1c"), Err(Err::Error(("1c", ErrorKind::Alpha))));
310
/// assert_eq!(alpha1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
311
/// ```
312
0
pub fn alpha1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
313
0
where
314
0
  T: Input,
315
0
  <T as Input>::Item: AsChar,
316
{
317
0
  input.split_at_position1(|item| !item.is_alpha(), ErrorKind::Alpha)
318
0
}
319
320
/// Recognizes zero or more ASCII numerical characters: 0-9
321
///
322
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
323
/// or if no terminating token is found (a non digit character).
324
/// # Example
325
///
326
/// ```
327
/// # use nom::{Err, error::ErrorKind, IResult, Needed};
328
/// # use nom::character::streaming::digit0;
329
/// assert_eq!(digit0::<_, (_, ErrorKind)>("21c"), Ok(("c", "21")));
330
/// assert_eq!(digit0::<_, (_, ErrorKind)>("a21c"), Ok(("a21c", "")));
331
/// assert_eq!(digit0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
332
/// ```
333
0
pub fn digit0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
334
0
where
335
0
  T: Input,
336
0
  <T as Input>::Item: AsChar,
337
{
338
0
  input.split_at_position(|item| !item.is_dec_digit())
339
0
}
340
341
/// Recognizes one or more ASCII numerical characters: 0-9
342
///
343
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
344
/// or if no terminating token is found (a non digit character).
345
/// # Example
346
///
347
/// ```
348
/// # use nom::{Err, error::ErrorKind, IResult, Needed};
349
/// # use nom::character::streaming::digit1;
350
/// assert_eq!(digit1::<_, (_, ErrorKind)>("21c"), Ok(("c", "21")));
351
/// assert_eq!(digit1::<_, (_, ErrorKind)>("c1"), Err(Err::Error(("c1", ErrorKind::Digit))));
352
/// assert_eq!(digit1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
353
/// ```
354
0
pub fn digit1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
355
0
where
356
0
  T: Input,
357
0
  <T as Input>::Item: AsChar,
358
{
359
0
  input.split_at_position1(|item| !item.is_dec_digit(), ErrorKind::Digit)
360
0
}
361
362
/// Recognizes zero or more ASCII hexadecimal numerical characters: 0-9, A-F, a-f
363
///
364
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
365
/// or if no terminating token is found (a non hexadecimal digit character).
366
/// # Example
367
///
368
/// ```
369
/// # use nom::{Err, error::ErrorKind, IResult, Needed};
370
/// # use nom::character::streaming::hex_digit0;
371
/// assert_eq!(hex_digit0::<_, (_, ErrorKind)>("21cZ"), Ok(("Z", "21c")));
372
/// assert_eq!(hex_digit0::<_, (_, ErrorKind)>("Z21c"), Ok(("Z21c", "")));
373
/// assert_eq!(hex_digit0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
374
/// ```
375
0
pub fn hex_digit0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
376
0
where
377
0
  T: Input,
378
0
  <T as Input>::Item: AsChar,
379
{
380
0
  input.split_at_position(|item| !item.is_hex_digit())
381
0
}
382
383
/// Recognizes one or more ASCII hexadecimal numerical characters: 0-9, A-F, a-f
384
///
385
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
386
/// or if no terminating token is found (a non hexadecimal digit character).
387
/// # Example
388
///
389
/// ```
390
/// # use nom::{Err, error::ErrorKind, IResult, Needed};
391
/// # use nom::character::streaming::hex_digit1;
392
/// assert_eq!(hex_digit1::<_, (_, ErrorKind)>("21cZ"), Ok(("Z", "21c")));
393
/// assert_eq!(hex_digit1::<_, (_, ErrorKind)>("H2"), Err(Err::Error(("H2", ErrorKind::HexDigit))));
394
/// assert_eq!(hex_digit1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
395
/// ```
396
0
pub fn hex_digit1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
397
0
where
398
0
  T: Input,
399
0
  <T as Input>::Item: AsChar,
400
{
401
0
  input.split_at_position1(|item| !item.is_hex_digit(), ErrorKind::HexDigit)
402
0
}
403
404
/// Recognizes zero or more octal characters: 0-7
405
///
406
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
407
/// or if no terminating token is found (a non octal digit character).
408
/// # Example
409
///
410
/// ```
411
/// # use nom::{Err, error::ErrorKind, IResult, Needed};
412
/// # use nom::character::streaming::oct_digit0;
413
/// assert_eq!(oct_digit0::<_, (_, ErrorKind)>("21cZ"), Ok(("cZ", "21")));
414
/// assert_eq!(oct_digit0::<_, (_, ErrorKind)>("Z21c"), Ok(("Z21c", "")));
415
/// assert_eq!(oct_digit0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
416
/// ```
417
0
pub fn oct_digit0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
418
0
where
419
0
  T: Input,
420
0
  <T as Input>::Item: AsChar,
421
{
422
0
  input.split_at_position(|item| !item.is_oct_digit())
423
0
}
424
425
/// Recognizes one or more octal characters: 0-7
426
///
427
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
428
/// or if no terminating token is found (a non octal digit character).
429
/// # Example
430
///
431
/// ```
432
/// # use nom::{Err, error::ErrorKind, IResult, Needed};
433
/// # use nom::character::streaming::oct_digit1;
434
/// assert_eq!(oct_digit1::<_, (_, ErrorKind)>("21cZ"), Ok(("cZ", "21")));
435
/// assert_eq!(oct_digit1::<_, (_, ErrorKind)>("H2"), Err(Err::Error(("H2", ErrorKind::OctDigit))));
436
/// assert_eq!(oct_digit1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
437
/// ```
438
0
pub fn oct_digit1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
439
0
where
440
0
  T: Input,
441
0
  <T as Input>::Item: AsChar,
442
{
443
0
  input.split_at_position1(|item| !item.is_oct_digit(), ErrorKind::OctDigit)
444
0
}
445
446
/// Recognizes zero or more binary characters: 0-1
447
///
448
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
449
/// or if no terminating token is found (a non binary digit character).
450
/// # Example
451
///
452
/// ```
453
/// # use nom::{Err, error::ErrorKind, IResult, Needed};
454
/// # use nom::character::streaming::bin_digit0;
455
/// assert_eq!(bin_digit0::<_, (_, ErrorKind)>("013a"), Ok(("3a", "01")));
456
/// assert_eq!(bin_digit0::<_, (_, ErrorKind)>("a013"), Ok(("a013", "")));
457
/// assert_eq!(bin_digit0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
458
/// ```
459
0
pub fn bin_digit0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
460
0
where
461
0
  T: Input,
462
0
  <T as Input>::Item: AsChar,
463
{
464
0
  input.split_at_position(|item| !item.is_bin_digit())
465
0
}
466
467
/// Recognizes one or more binary characters: 0-1
468
///
469
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
470
/// or if no terminating token is found (a non binary digit character).
471
/// # Example
472
///
473
/// ```
474
/// # use nom::{Err, error::ErrorKind, IResult, Needed};
475
/// # use nom::character::streaming::bin_digit1;
476
/// assert_eq!(bin_digit1::<_, (_, ErrorKind)>("013a"), Ok(("3a", "01")));
477
/// assert_eq!(bin_digit1::<_, (_, ErrorKind)>("a013"), Err(Err::Error(("a013", ErrorKind::BinDigit))));
478
/// assert_eq!(bin_digit1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
479
/// ```
480
0
pub fn bin_digit1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
481
0
where
482
0
  T: Input,
483
0
  <T as Input>::Item: AsChar,
484
{
485
0
  input.split_at_position1(|item| !item.is_bin_digit(), ErrorKind::BinDigit)
486
0
}
487
488
/// Recognizes zero or more ASCII numerical and alphabetic characters: 0-9, a-z, A-Z
489
///
490
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
491
/// or if no terminating token is found (a non alphanumerical character).
492
/// # Example
493
///
494
/// ```
495
/// # use nom::{Err, error::ErrorKind, IResult, Needed};
496
/// # use nom::character::streaming::alphanumeric0;
497
/// assert_eq!(alphanumeric0::<_, (_, ErrorKind)>("21cZ%1"), Ok(("%1", "21cZ")));
498
/// assert_eq!(alphanumeric0::<_, (_, ErrorKind)>("&Z21c"), Ok(("&Z21c", "")));
499
/// assert_eq!(alphanumeric0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
500
/// ```
501
0
pub fn alphanumeric0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
502
0
where
503
0
  T: Input,
504
0
  <T as Input>::Item: AsChar,
505
{
506
0
  input.split_at_position(|item| !item.is_alphanum())
507
0
}
508
509
/// Recognizes one or more ASCII numerical and alphabetic characters: 0-9, a-z, A-Z
510
///
511
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
512
/// or if no terminating token is found (a non alphanumerical character).
513
/// # Example
514
///
515
/// ```
516
/// # use nom::{Err, error::ErrorKind, IResult, Needed};
517
/// # use nom::character::streaming::alphanumeric1;
518
/// assert_eq!(alphanumeric1::<_, (_, ErrorKind)>("21cZ%1"), Ok(("%1", "21cZ")));
519
/// assert_eq!(alphanumeric1::<_, (_, ErrorKind)>("&H2"), Err(Err::Error(("&H2", ErrorKind::AlphaNumeric))));
520
/// assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
521
/// ```
522
0
pub fn alphanumeric1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
523
0
where
524
0
  T: Input,
525
0
  <T as Input>::Item: AsChar,
526
{
527
0
  input.split_at_position1(|item| !item.is_alphanum(), ErrorKind::AlphaNumeric)
528
0
}
529
530
/// Recognizes zero or more spaces and tabs.
531
///
532
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
533
/// or if no terminating token is found (a non space character).
534
/// # Example
535
///
536
/// ```
537
/// # use nom::{Err, error::ErrorKind, IResult, Needed};
538
/// # use nom::character::streaming::space0;
539
/// assert_eq!(space0::<_, (_, ErrorKind)>(" \t21c"), Ok(("21c", " \t")));
540
/// assert_eq!(space0::<_, (_, ErrorKind)>("Z21c"), Ok(("Z21c", "")));
541
/// assert_eq!(space0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
542
/// ```
543
0
pub fn space0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
544
0
where
545
0
  T: Input,
546
0
  <T as Input>::Item: AsChar,
547
{
548
0
  input.split_at_position(|item| {
549
0
    let c = item.as_char();
550
0
    !(c == ' ' || c == '\t')
551
0
  })
552
0
}
553
/// Recognizes one or more spaces and tabs.
554
///
555
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
556
/// or if no terminating token is found (a non space character).
557
/// # Example
558
///
559
/// ```
560
/// # use nom::{Err, error::ErrorKind, IResult, Needed};
561
/// # use nom::character::streaming::space1;
562
/// assert_eq!(space1::<_, (_, ErrorKind)>(" \t21c"), Ok(("21c", " \t")));
563
/// assert_eq!(space1::<_, (_, ErrorKind)>("H2"), Err(Err::Error(("H2", ErrorKind::Space))));
564
/// assert_eq!(space1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
565
/// ```
566
0
pub fn space1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
567
0
where
568
0
  T: Input,
569
0
  <T as Input>::Item: AsChar,
570
{
571
0
  input.split_at_position1(
572
0
    |item| {
573
0
      let c = item.as_char();
574
0
      !(c == ' ' || c == '\t')
575
0
    },
576
0
    ErrorKind::Space,
577
  )
578
0
}
579
580
/// Recognizes zero or more spaces, tabs, carriage returns and line feeds.
581
///
582
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
583
/// or if no terminating token is found (a non space character).
584
/// # Example
585
///
586
/// ```
587
/// # use nom::{Err, error::ErrorKind, IResult, Needed};
588
/// # use nom::character::streaming::multispace0;
589
/// assert_eq!(multispace0::<_, (_, ErrorKind)>(" \t\n\r21c"), Ok(("21c", " \t\n\r")));
590
/// assert_eq!(multispace0::<_, (_, ErrorKind)>("Z21c"), Ok(("Z21c", "")));
591
/// assert_eq!(multispace0::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
592
/// ```
593
0
pub fn multispace0<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
594
0
where
595
0
  T: Input,
596
0
  <T as Input>::Item: AsChar,
597
{
598
0
  input.split_at_position(|item| {
599
0
    let c = item.as_char();
600
0
    !(c == ' ' || c == '\t' || c == '\r' || c == '\n')
601
0
  })
602
0
}
603
604
/// Recognizes one or more spaces, tabs, carriage returns and line feeds.
605
///
606
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data,
607
/// or if no terminating token is found (a non space character).
608
/// # Example
609
///
610
/// ```
611
/// # use nom::{Err, error::ErrorKind, IResult, Needed};
612
/// # use nom::character::streaming::multispace1;
613
/// assert_eq!(multispace1::<_, (_, ErrorKind)>(" \t\n\r21c"), Ok(("21c", " \t\n\r")));
614
/// assert_eq!(multispace1::<_, (_, ErrorKind)>("H2"), Err(Err::Error(("H2", ErrorKind::MultiSpace))));
615
/// assert_eq!(multispace1::<_, (_, ErrorKind)>(""), Err(Err::Incomplete(Needed::new(1))));
616
/// ```
617
0
pub fn multispace1<T, E: ParseError<T>>(input: T) -> IResult<T, T, E>
618
0
where
619
0
  T: Input,
620
0
  <T as Input>::Item: AsChar,
621
{
622
0
  input.split_at_position1(
623
0
    |item| {
624
0
      let c = item.as_char();
625
0
      !(c == ' ' || c == '\t' || c == '\r' || c == '\n')
626
0
    },
627
0
    ErrorKind::MultiSpace,
628
  )
629
0
}
630
631
0
pub(crate) fn sign<T, E: ParseError<T>>(input: T) -> IResult<T, bool, E>
632
0
where
633
0
  T: Clone + Input,
634
0
  T: for<'a> Compare<&'a [u8]>,
635
{
636
  use crate::bytes::streaming::tag;
637
  use crate::combinator::value;
638
639
0
  let (i, opt_sign) = opt(alt((
640
0
    value(false, tag(&b"-"[..])),
641
0
    value(true, tag(&b"+"[..])),
642
0
  )))
643
0
  .parse(input)?;
644
0
  let sign = opt_sign.unwrap_or(true);
645
646
0
  Ok((i, sign))
647
0
}
648
649
#[doc(hidden)]
650
macro_rules! ints {
651
    ($($t:tt)+) => {
652
        $(
653
        /// will parse a number in text form to a number
654
        ///
655
        /// *Complete version*: can parse until the end of input.
656
0
        pub fn $t<T, E: ParseError<T>>(input: T) -> IResult<T, $t, E>
657
0
            where
658
0
            T: Input +  Clone,
659
0
            <T as Input>::Item: AsChar,
660
0
            T: for <'a> Compare<&'a[u8]>,
661
            {
662
0
              let (i, sign) = sign(input.clone())?;
663
664
0
                if i.input_len() == 0 {
665
0
                    return Err(Err::Incomplete(Needed::new(1)));
666
0
                }
667
668
0
                let mut value: $t = 0;
669
0
                if sign {
670
0
                    let mut pos = 0;
671
0
                    for c in i.iter_elements() {
672
0
                        match c.as_char().to_digit(10) {
673
                            None => {
674
0
                                if pos == 0 {
675
0
                                    return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit)));
676
                                } else {
677
0
                                    return Ok((i.take_from(pos), value));
678
                                }
679
                            },
680
0
                            Some(d) => match value.checked_mul(10).and_then(|v| v.checked_add(d as $t)) {
Unexecuted instantiation: nom::character::streaming::i8::<_, _>::{closure#0}
Unexecuted instantiation: nom::character::streaming::i16::<_, _>::{closure#0}
Unexecuted instantiation: nom::character::streaming::i32::<_, _>::{closure#0}
Unexecuted instantiation: nom::character::streaming::i64::<_, _>::{closure#0}
Unexecuted instantiation: nom::character::streaming::i128::<_, _>::{closure#0}
Unexecuted instantiation: nom::character::streaming::isize::<_, _>::{closure#0}
681
0
                                None => return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit))),
682
0
                                Some(v) => {
683
0
                                  pos += c.len();
684
0
                                  value = v;
685
0
                                },
686
                            }
687
                        }
688
                    }
689
                } else {
690
0
                    let mut pos = 0;
691
0
                    for c in i.iter_elements() {
692
0
                        match c.as_char().to_digit(10) {
693
                            None => {
694
0
                                if pos == 0 {
695
0
                                    return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit)));
696
                                } else {
697
0
                                    return Ok((i.take_from(pos), value));
698
                                }
699
                            },
700
0
                            Some(d) => match value.checked_mul(10).and_then(|v| v.checked_sub(d as $t)) {
Unexecuted instantiation: nom::character::streaming::i8::<_, _>::{closure#1}
Unexecuted instantiation: nom::character::streaming::i16::<_, _>::{closure#1}
Unexecuted instantiation: nom::character::streaming::i32::<_, _>::{closure#1}
Unexecuted instantiation: nom::character::streaming::i64::<_, _>::{closure#1}
Unexecuted instantiation: nom::character::streaming::i128::<_, _>::{closure#1}
Unexecuted instantiation: nom::character::streaming::isize::<_, _>::{closure#1}
701
0
                                None => return Err(Err::Error(E::from_error_kind(input, ErrorKind::Digit))),
702
0
                                Some(v) => {
703
0
                                  pos += c.len();
704
0
                                  value = v;
705
0
                                },
706
                            }
707
                        }
708
                    }
709
                }
710
711
0
                Err(Err::Incomplete(Needed::new(1)))
712
0
            }
Unexecuted instantiation: nom::character::streaming::i8::<_, _>
Unexecuted instantiation: nom::character::streaming::i16::<_, _>
Unexecuted instantiation: nom::character::streaming::i32::<_, _>
Unexecuted instantiation: nom::character::streaming::i64::<_, _>
Unexecuted instantiation: nom::character::streaming::i128::<_, _>
Unexecuted instantiation: nom::character::streaming::isize::<_, _>
713
        )+
714
    }
715
}
716
717
ints! { i8 i16 i32 i64 i128 isize }
718
719
#[doc(hidden)]
720
macro_rules! uints {
721
    ($($t:tt)+) => {
722
        $(
723
        /// will parse a number in text form to a number
724
        ///
725
        /// *Complete version*: can parse until the end of input.
726
0
        pub fn $t<T, E: ParseError<T>>(input: T) -> IResult<T, $t, E>
727
0
            where
728
0
            T: Input ,
729
0
            <T as Input>::Item: AsChar,
730
            {
731
0
                let i = input;
732
733
0
                if i.input_len() == 0 {
734
0
                    return Err(Err::Incomplete(Needed::new(1)));
735
0
                }
736
737
0
                let mut value: $t = 0;
738
0
                let mut pos = 0;
739
0
                for c in i.iter_elements() {
740
0
                    match c.as_char().to_digit(10) {
741
                        None => {
742
0
                            if pos == 0 {
743
0
                                return Err(Err::Error(E::from_error_kind(i, ErrorKind::Digit)));
744
                            } else {
745
0
                                return Ok((i.take_from(pos), value));
746
                            }
747
                        },
748
0
                        Some(d) => match value.checked_mul(10).and_then(|v| v.checked_add(d as $t)) {
Unexecuted instantiation: nom::character::streaming::u8::<_, _>::{closure#0}
Unexecuted instantiation: nom::character::streaming::u16::<_, _>::{closure#0}
Unexecuted instantiation: nom::character::streaming::u32::<_, _>::{closure#0}
Unexecuted instantiation: nom::character::streaming::u64::<_, _>::{closure#0}
Unexecuted instantiation: nom::character::streaming::u128::<_, _>::{closure#0}
Unexecuted instantiation: nom::character::streaming::usize::<_, _>::{closure#0}
749
0
                            None => return Err(Err::Error(E::from_error_kind(i, ErrorKind::Digit))),
750
0
                            Some(v) => {
751
0
                              pos += c.len();
752
0
                              value = v;
753
0
                            },
754
                        }
755
                    }
756
                }
757
758
0
                Err(Err::Incomplete(Needed::new(1)))
759
0
            }
Unexecuted instantiation: nom::character::streaming::u8::<_, _>
Unexecuted instantiation: nom::character::streaming::u16::<_, _>
Unexecuted instantiation: nom::character::streaming::u32::<_, _>
Unexecuted instantiation: nom::character::streaming::u64::<_, _>
Unexecuted instantiation: nom::character::streaming::u128::<_, _>
Unexecuted instantiation: nom::character::streaming::usize::<_, _>
760
        )+
761
    }
762
}
763
764
uints! { u8 u16 u32 u64 u128 usize }
765
766
#[cfg(test)]
767
mod tests {
768
  use super::*;
769
  use crate::error::ErrorKind;
770
  use crate::internal::{Err, Needed};
771
  use crate::sequence::pair;
772
  use crate::traits::ParseTo;
773
  use crate::Parser;
774
  use proptest::prelude::*;
775
776
  macro_rules! assert_parse(
777
    ($left: expr, $right: expr) => {
778
      let res: $crate::IResult<_, _, (_, ErrorKind)> = $left;
779
      assert_eq!(res, $right);
780
    };
781
  );
782
783
  #[test]
784
  fn anychar_str() {
785
    use super::anychar;
786
    assert_eq!(anychar::<_, (&str, ErrorKind)>("Ә"), Ok(("", 'Ә')));
787
  }
788
789
  #[test]
790
  fn character() {
791
    let a: &[u8] = b"abcd";
792
    let b: &[u8] = b"1234";
793
    let c: &[u8] = b"a123";
794
    let d: &[u8] = "azé12".as_bytes();
795
    let e: &[u8] = b" ";
796
    let f: &[u8] = b" ;";
797
    //assert_eq!(alpha1::<_, (_, ErrorKind)>(a), Err(Err::Incomplete(Needed::new(1))));
798
    assert_parse!(alpha1(a), Err(Err::Incomplete(Needed::new(1))));
799
    assert_eq!(alpha1(b), Err(Err::Error((b, ErrorKind::Alpha))));
800
    assert_eq!(alpha1::<_, (_, ErrorKind)>(c), Ok((&c[1..], &b"a"[..])));
801
    assert_eq!(
802
      alpha1::<_, (_, ErrorKind)>(d),
803
      Ok(("é12".as_bytes(), &b"az"[..]))
804
    );
805
    assert_eq!(digit1(a), Err(Err::Error((a, ErrorKind::Digit))));
806
    assert_eq!(
807
      digit1::<_, (_, ErrorKind)>(b),
808
      Err(Err::Incomplete(Needed::new(1)))
809
    );
810
    assert_eq!(digit1(c), Err(Err::Error((c, ErrorKind::Digit))));
811
    assert_eq!(digit1(d), Err(Err::Error((d, ErrorKind::Digit))));
812
    assert_eq!(
813
      hex_digit1::<_, (_, ErrorKind)>(a),
814
      Err(Err::Incomplete(Needed::new(1)))
815
    );
816
    assert_eq!(
817
      hex_digit1::<_, (_, ErrorKind)>(b),
818
      Err(Err::Incomplete(Needed::new(1)))
819
    );
820
    assert_eq!(
821
      hex_digit1::<_, (_, ErrorKind)>(c),
822
      Err(Err::Incomplete(Needed::new(1)))
823
    );
824
    assert_eq!(
825
      hex_digit1::<_, (_, ErrorKind)>(d),
826
      Ok(("zé12".as_bytes(), &b"a"[..]))
827
    );
828
    assert_eq!(hex_digit1(e), Err(Err::Error((e, ErrorKind::HexDigit))));
829
    assert_eq!(oct_digit1(a), Err(Err::Error((a, ErrorKind::OctDigit))));
830
    assert_eq!(
831
      oct_digit1::<_, (_, ErrorKind)>(b),
832
      Err(Err::Incomplete(Needed::new(1)))
833
    );
834
    assert_eq!(oct_digit1(c), Err(Err::Error((c, ErrorKind::OctDigit))));
835
    assert_eq!(oct_digit1(d), Err(Err::Error((d, ErrorKind::OctDigit))));
836
    assert_eq!(
837
      alphanumeric1::<_, (_, ErrorKind)>(a),
838
      Err(Err::Incomplete(Needed::new(1)))
839
    );
840
    assert_eq!(bin_digit1(a), Err(Err::Error((a, ErrorKind::BinDigit))));
841
    assert_eq!(
842
      bin_digit1::<_, (_, ErrorKind)>(b),
843
      Ok((&b"234"[..], &b"1"[..]))
844
    );
845
    assert_eq!(bin_digit1(c), Err(Err::Error((c, ErrorKind::BinDigit))));
846
    assert_eq!(bin_digit1(d), Err(Err::Error((d, ErrorKind::BinDigit))));
847
    assert_eq!(
848
      alphanumeric1::<_, (_, ErrorKind)>(a),
849
      Err(Err::Incomplete(Needed::new(1)))
850
    );
851
    //assert_eq!(fix_error!(b,(), alphanumeric1), Ok((empty, b)));
852
    assert_eq!(
853
      alphanumeric1::<_, (_, ErrorKind)>(c),
854
      Err(Err::Incomplete(Needed::new(1)))
855
    );
856
    assert_eq!(
857
      alphanumeric1::<_, (_, ErrorKind)>(d),
858
      Ok(("é12".as_bytes(), &b"az"[..]))
859
    );
860
    assert_eq!(
861
      space1::<_, (_, ErrorKind)>(e),
862
      Err(Err::Incomplete(Needed::new(1)))
863
    );
864
    assert_eq!(space1::<_, (_, ErrorKind)>(f), Ok((&b";"[..], &b" "[..])));
865
  }
866
867
  #[cfg(feature = "alloc")]
868
  #[test]
869
  fn character_s() {
870
    let a = "abcd";
871
    let b = "1234";
872
    let c = "a123";
873
    let d = "azé12";
874
    let e = " ";
875
    assert_eq!(
876
      alpha1::<_, (_, ErrorKind)>(a),
877
      Err(Err::Incomplete(Needed::new(1)))
878
    );
879
    assert_eq!(alpha1(b), Err(Err::Error((b, ErrorKind::Alpha))));
880
    assert_eq!(alpha1::<_, (_, ErrorKind)>(c), Ok((&c[1..], "a")));
881
    assert_eq!(alpha1::<_, (_, ErrorKind)>(d), Ok(("é12", "az")));
882
    assert_eq!(digit1(a), Err(Err::Error((a, ErrorKind::Digit))));
883
    assert_eq!(
884
      digit1::<_, (_, ErrorKind)>(b),
885
      Err(Err::Incomplete(Needed::new(1)))
886
    );
887
    assert_eq!(digit1(c), Err(Err::Error((c, ErrorKind::Digit))));
888
    assert_eq!(digit1(d), Err(Err::Error((d, ErrorKind::Digit))));
889
    assert_eq!(
890
      hex_digit1::<_, (_, ErrorKind)>(a),
891
      Err(Err::Incomplete(Needed::new(1)))
892
    );
893
    assert_eq!(
894
      hex_digit1::<_, (_, ErrorKind)>(b),
895
      Err(Err::Incomplete(Needed::new(1)))
896
    );
897
    assert_eq!(
898
      hex_digit1::<_, (_, ErrorKind)>(c),
899
      Err(Err::Incomplete(Needed::new(1)))
900
    );
901
    assert_eq!(hex_digit1::<_, (_, ErrorKind)>(d), Ok(("zé12", "a")));
902
    assert_eq!(hex_digit1(e), Err(Err::Error((e, ErrorKind::HexDigit))));
903
    assert_eq!(oct_digit1(a), Err(Err::Error((a, ErrorKind::OctDigit))));
904
    assert_eq!(
905
      oct_digit1::<_, (_, ErrorKind)>(b),
906
      Err(Err::Incomplete(Needed::new(1)))
907
    );
908
    assert_eq!(oct_digit1(c), Err(Err::Error((c, ErrorKind::OctDigit))));
909
    assert_eq!(oct_digit1(d), Err(Err::Error((d, ErrorKind::OctDigit))));
910
    assert_eq!(bin_digit1(a), Err(Err::Error((a, ErrorKind::BinDigit))));
911
    assert_eq!(bin_digit1::<_, (_, ErrorKind)>(b), Ok(("234", "1")));
912
    assert_eq!(bin_digit1(c), Err(Err::Error((c, ErrorKind::BinDigit))));
913
    assert_eq!(bin_digit1(d), Err(Err::Error((d, ErrorKind::BinDigit))));
914
    assert_eq!(
915
      alphanumeric1::<_, (_, ErrorKind)>(a),
916
      Err(Err::Incomplete(Needed::new(1)))
917
    );
918
    //assert_eq!(fix_error!(b,(), alphanumeric1), Ok((empty, b)));
919
    assert_eq!(
920
      alphanumeric1::<_, (_, ErrorKind)>(c),
921
      Err(Err::Incomplete(Needed::new(1)))
922
    );
923
    assert_eq!(alphanumeric1::<_, (_, ErrorKind)>(d), Ok(("é12", "az")));
924
    assert_eq!(
925
      space1::<_, (_, ErrorKind)>(e),
926
      Err(Err::Incomplete(Needed::new(1)))
927
    );
928
  }
929
930
  use crate::traits::Offset;
931
  #[test]
932
  fn offset() {
933
    let a = &b"abcd;"[..];
934
    let b = &b"1234;"[..];
935
    let c = &b"a123;"[..];
936
    let d = &b" \t;"[..];
937
    let e = &b" \t\r\n;"[..];
938
    let f = &b"123abcDEF;"[..];
939
940
    match alpha1::<_, (_, ErrorKind)>(a) {
941
      Ok((i, _)) => {
942
        assert_eq!(a.offset(i) + i.len(), a.len());
943
      }
944
      _ => panic!("wrong return type in offset test for alpha"),
945
    }
946
    match digit1::<_, (_, ErrorKind)>(b) {
947
      Ok((i, _)) => {
948
        assert_eq!(b.offset(i) + i.len(), b.len());
949
      }
950
      _ => panic!("wrong return type in offset test for digit"),
951
    }
952
    match alphanumeric1::<_, (_, ErrorKind)>(c) {
953
      Ok((i, _)) => {
954
        assert_eq!(c.offset(i) + i.len(), c.len());
955
      }
956
      _ => panic!("wrong return type in offset test for alphanumeric"),
957
    }
958
    match space1::<_, (_, ErrorKind)>(d) {
959
      Ok((i, _)) => {
960
        assert_eq!(d.offset(i) + i.len(), d.len());
961
      }
962
      _ => panic!("wrong return type in offset test for space"),
963
    }
964
    match multispace1::<_, (_, ErrorKind)>(e) {
965
      Ok((i, _)) => {
966
        assert_eq!(e.offset(i) + i.len(), e.len());
967
      }
968
      _ => panic!("wrong return type in offset test for multispace"),
969
    }
970
    match hex_digit1::<_, (_, ErrorKind)>(f) {
971
      Ok((i, _)) => {
972
        assert_eq!(f.offset(i) + i.len(), f.len());
973
      }
974
      _ => panic!("wrong return type in offset test for hex_digit"),
975
    }
976
    match oct_digit1::<_, (_, ErrorKind)>(f) {
977
      Ok((i, _)) => {
978
        assert_eq!(f.offset(i) + i.len(), f.len());
979
      }
980
      _ => panic!("wrong return type in offset test for oct_digit"),
981
    }
982
    match bin_digit1::<_, (_, ErrorKind)>(f) {
983
      Ok((i, _)) => {
984
        assert_eq!(f.offset(i) + i.len(), f.len());
985
      }
986
      _ => panic!("wrong return type in offset test for bin_digit"),
987
    }
988
  }
989
990
  #[test]
991
  fn is_not_line_ending_bytes() {
992
    let a: &[u8] = b"ab12cd\nefgh";
993
    assert_eq!(
994
      not_line_ending::<_, (_, ErrorKind)>(a),
995
      Ok((&b"\nefgh"[..], &b"ab12cd"[..]))
996
    );
997
998
    let b: &[u8] = b"ab12cd\nefgh\nijkl";
999
    assert_eq!(
1000
      not_line_ending::<_, (_, ErrorKind)>(b),
1001
      Ok((&b"\nefgh\nijkl"[..], &b"ab12cd"[..]))
1002
    );
1003
1004
    let c: &[u8] = b"ab12cd\r\nefgh\nijkl";
1005
    assert_eq!(
1006
      not_line_ending::<_, (_, ErrorKind)>(c),
1007
      Ok((&b"\r\nefgh\nijkl"[..], &b"ab12cd"[..]))
1008
    );
1009
1010
    let d: &[u8] = b"ab12cd";
1011
    assert_eq!(
1012
      not_line_ending::<_, (_, ErrorKind)>(d),
1013
      Err(Err::Incomplete(Needed::Unknown))
1014
    );
1015
  }
1016
1017
  #[test]
1018
  fn is_not_line_ending_str() {
1019
    /*
1020
    let a: &str = "ab12cd\nefgh";
1021
    assert_eq!(not_line_ending(a), Ok((&"\nefgh"[..], &"ab12cd"[..])));
1022
1023
    let b: &str = "ab12cd\nefgh\nijkl";
1024
    assert_eq!(not_line_ending(b), Ok((&"\nefgh\nijkl"[..], &"ab12cd"[..])));
1025
1026
    let c: &str = "ab12cd\r\nefgh\nijkl";
1027
    assert_eq!(not_line_ending(c), Ok((&"\r\nefgh\nijkl"[..], &"ab12cd"[..])));
1028
1029
    let d = "βèƒôřè\nÂßÇáƒƭèř";
1030
    assert_eq!(not_line_ending(d), Ok((&"\nÂßÇáƒƭèř"[..], &"βèƒôřè"[..])));
1031
1032
    let e = "βèƒôřè\r\nÂßÇáƒƭèř";
1033
    assert_eq!(not_line_ending(e), Ok((&"\r\nÂßÇáƒƭèř"[..], &"βèƒôřè"[..])));
1034
    */
1035
1036
    let f = "βèƒôřè\rÂßÇáƒƭèř";
1037
    assert_eq!(not_line_ending(f), Err(Err::Error((f, ErrorKind::Tag))));
1038
1039
    let g2: &str = "ab12cd";
1040
    assert_eq!(
1041
      not_line_ending::<_, (_, ErrorKind)>(g2),
1042
      Err(Err::Incomplete(Needed::Unknown))
1043
    );
1044
  }
1045
1046
  #[test]
1047
  fn hex_digit_test() {
1048
    let i = &b"0123456789abcdefABCDEF;"[..];
1049
    assert_parse!(hex_digit1(i), Ok((&b";"[..], &i[..i.len() - 1])));
1050
1051
    let i = &b"g"[..];
1052
    assert_parse!(
1053
      hex_digit1(i),
1054
      Err(Err::Error(error_position!(i, ErrorKind::HexDigit)))
1055
    );
1056
1057
    let i = &b"G"[..];
1058
    assert_parse!(
1059
      hex_digit1(i),
1060
      Err(Err::Error(error_position!(i, ErrorKind::HexDigit)))
1061
    );
1062
1063
    assert!(AsChar::is_hex_digit(b'0'));
1064
    assert!(AsChar::is_hex_digit(b'9'));
1065
    assert!(AsChar::is_hex_digit(b'a'));
1066
    assert!(AsChar::is_hex_digit(b'f'));
1067
    assert!(AsChar::is_hex_digit(b'A'));
1068
    assert!(AsChar::is_hex_digit(b'F'));
1069
    assert!(!AsChar::is_hex_digit(b'g'));
1070
    assert!(!AsChar::is_hex_digit(b'G'));
1071
    assert!(!AsChar::is_hex_digit(b'/'));
1072
    assert!(!AsChar::is_hex_digit(b':'));
1073
    assert!(!AsChar::is_hex_digit(b'@'));
1074
    assert!(!AsChar::is_hex_digit(b'\x60'));
1075
  }
1076
1077
  #[test]
1078
  fn oct_digit_test() {
1079
    let i = &b"01234567;"[..];
1080
    assert_parse!(oct_digit1(i), Ok((&b";"[..], &i[..i.len() - 1])));
1081
1082
    let i = &b"8"[..];
1083
    assert_parse!(
1084
      oct_digit1(i),
1085
      Err(Err::Error(error_position!(i, ErrorKind::OctDigit)))
1086
    );
1087
1088
    assert!(AsChar::is_oct_digit(b'0'));
1089
    assert!(AsChar::is_oct_digit(b'7'));
1090
    assert!(!AsChar::is_oct_digit(b'8'));
1091
    assert!(!AsChar::is_oct_digit(b'9'));
1092
    assert!(!AsChar::is_oct_digit(b'a'));
1093
    assert!(!AsChar::is_oct_digit(b'A'));
1094
    assert!(!AsChar::is_oct_digit(b'/'));
1095
    assert!(!AsChar::is_oct_digit(b':'));
1096
    assert!(!AsChar::is_oct_digit(b'@'));
1097
    assert!(!AsChar::is_oct_digit(b'\x60'));
1098
  }
1099
1100
  #[test]
1101
  fn bin_digit_test() {
1102
    let i = &b"01;"[..];
1103
    assert_parse!(bin_digit1(i), Ok((&b";"[..], &i[..i.len() - 1])));
1104
1105
    let i = &b"8"[..];
1106
    assert_parse!(
1107
      bin_digit1(i),
1108
      Err(Err::Error(error_position!(i, ErrorKind::BinDigit)))
1109
    );
1110
1111
    assert!(crate::character::is_bin_digit(b'0'));
1112
    assert!(crate::character::is_bin_digit(b'1'));
1113
    assert!(!crate::character::is_bin_digit(b'8'));
1114
    assert!(!crate::character::is_bin_digit(b'9'));
1115
    assert!(!crate::character::is_bin_digit(b'a'));
1116
    assert!(!crate::character::is_bin_digit(b'A'));
1117
    assert!(!crate::character::is_bin_digit(b'/'));
1118
    assert!(!crate::character::is_bin_digit(b':'));
1119
    assert!(!crate::character::is_bin_digit(b'@'));
1120
    assert!(!crate::character::is_bin_digit(b'\x60'));
1121
  }
1122
1123
  #[test]
1124
  fn full_line_windows() {
1125
    fn take_full_line(i: &[u8]) -> IResult<&[u8], (&[u8], &[u8])> {
1126
      pair(not_line_ending, line_ending).parse(i)
1127
    }
1128
    let input = b"abc\r\n";
1129
    let output = take_full_line(input);
1130
    assert_eq!(output, Ok((&b""[..], (&b"abc"[..], &b"\r\n"[..]))));
1131
  }
1132
1133
  #[test]
1134
  fn full_line_unix() {
1135
    fn take_full_line(i: &[u8]) -> IResult<&[u8], (&[u8], &[u8])> {
1136
      pair(not_line_ending, line_ending).parse(i)
1137
    }
1138
    let input = b"abc\n";
1139
    let output = take_full_line(input);
1140
    assert_eq!(output, Ok((&b""[..], (&b"abc"[..], &b"\n"[..]))));
1141
  }
1142
1143
  #[test]
1144
  fn check_windows_lineending() {
1145
    let input = b"\r\n";
1146
    let output = line_ending(&input[..]);
1147
    assert_parse!(output, Ok((&b""[..], &b"\r\n"[..])));
1148
  }
1149
1150
  #[test]
1151
  fn check_unix_lineending() {
1152
    let input = b"\n";
1153
    let output = line_ending(&input[..]);
1154
    assert_parse!(output, Ok((&b""[..], &b"\n"[..])));
1155
  }
1156
1157
  #[test]
1158
  fn cr_lf() {
1159
    assert_parse!(crlf(&b"\r\na"[..]), Ok((&b"a"[..], &b"\r\n"[..])));
1160
    assert_parse!(crlf(&b"\r"[..]), Err(Err::Incomplete(Needed::new(2))));
1161
    assert_parse!(
1162
      crlf(&b"\ra"[..]),
1163
      Err(Err::Error(error_position!(&b"\ra"[..], ErrorKind::CrLf)))
1164
    );
1165
1166
    assert_parse!(crlf("\r\na"), Ok(("a", "\r\n")));
1167
    assert_parse!(crlf("\r"), Err(Err::Incomplete(Needed::new(2))));
1168
    assert_parse!(
1169
      crlf("\ra"),
1170
      Err(Err::Error(error_position!("\ra", ErrorKind::CrLf)))
1171
    );
1172
  }
1173
1174
  #[test]
1175
  fn end_of_line() {
1176
    assert_parse!(line_ending(&b"\na"[..]), Ok((&b"a"[..], &b"\n"[..])));
1177
    assert_parse!(line_ending(&b"\r\na"[..]), Ok((&b"a"[..], &b"\r\n"[..])));
1178
    assert_parse!(
1179
      line_ending(&b"\r"[..]),
1180
      Err(Err::Incomplete(Needed::new(2)))
1181
    );
1182
    assert_parse!(
1183
      line_ending(&b"\ra"[..]),
1184
      Err(Err::Error(error_position!(&b"\ra"[..], ErrorKind::CrLf)))
1185
    );
1186
1187
    assert_parse!(line_ending("\na"), Ok(("a", "\n")));
1188
    assert_parse!(line_ending("\r\na"), Ok(("a", "\r\n")));
1189
    assert_parse!(line_ending("\r"), Err(Err::Incomplete(Needed::new(2))));
1190
    assert_parse!(
1191
      line_ending("\ra"),
1192
      Err(Err::Error(error_position!("\ra", ErrorKind::CrLf)))
1193
    );
1194
  }
1195
1196
  fn digit_to_i16(input: &str) -> IResult<&str, i16> {
1197
    let i = input;
1198
    let (i, opt_sign) = opt(alt((char('+'), char('-')))).parse(i)?;
1199
    let sign = match opt_sign {
1200
      Some('+') => true,
1201
      Some('-') => false,
1202
      _ => true,
1203
    };
1204
1205
    let (i, s) = match digit1::<_, crate::error::Error<_>>(i) {
1206
      Ok((i, s)) => (i, s),
1207
      Err(Err::Incomplete(i)) => return Err(Err::Incomplete(i)),
1208
      Err(_) => {
1209
        return Err(Err::Error(crate::error::Error::from_error_kind(
1210
          input,
1211
          ErrorKind::Digit,
1212
        )))
1213
      }
1214
    };
1215
    match s.parse_to() {
1216
      Some(n) => {
1217
        if sign {
1218
          Ok((i, n))
1219
        } else {
1220
          Ok((i, -n))
1221
        }
1222
      }
1223
      None => Err(Err::Error(crate::error::Error::from_error_kind(
1224
        i,
1225
        ErrorKind::Digit,
1226
      ))),
1227
    }
1228
  }
1229
1230
  fn digit_to_u32(i: &str) -> IResult<&str, u32> {
1231
    let (i, s) = digit1(i)?;
1232
    match s.parse_to() {
1233
      Some(n) => Ok((i, n)),
1234
      None => Err(Err::Error(crate::error::Error::from_error_kind(
1235
        i,
1236
        ErrorKind::Digit,
1237
      ))),
1238
    }
1239
  }
1240
1241
  proptest! {
1242
    #[test]
1243
    fn ints(s in "\\PC*") {
1244
        let res1 = digit_to_i16(&s);
1245
        let res2 = i16(s.as_str());
1246
        assert_eq!(res1, res2);
1247
    }
1248
1249
    #[test]
1250
    fn uints(s in "\\PC*") {
1251
        let res1 = digit_to_u32(&s);
1252
        let res2 = u32(s.as_str());
1253
        assert_eq!(res1, res2);
1254
    }
1255
  }
1256
}