Coverage Report

Created: 2025-11-16 07:09

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