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-8.0.0/src/error.rs
Line
Count
Source
1
//! Error management
2
//!
3
//! Parsers are generic over their error type, requiring that it implements
4
//! the `error::ParseError<Input>` trait.
5
6
use crate::internal::{Err, Mode, OutputMode, PResult, Parser};
7
use crate::lib::std::fmt;
8
9
#[cfg(feature = "alloc")]
10
use crate::alloc::borrow::ToOwned;
11
12
#[cfg(feature = "std")]
13
use crate::internal::IResult;
14
15
/// This trait must be implemented by the error type of a nom parser.
16
///
17
/// There are already implementations of it for `(Input, ErrorKind)`
18
/// and `Error<Input>`.
19
///
20
/// It provides methods to create an error from some combinators,
21
/// and combine existing errors in combinators like `alt`.
22
pub trait ParseError<I>: Sized {
23
  /// Creates an error from the input position and an [ErrorKind]
24
  fn from_error_kind(input: I, kind: ErrorKind) -> Self;
25
26
  /// Combines an existing error with a new one created from the input
27
  /// position and an [ErrorKind]. This is useful when backtracking
28
  /// through a parse tree, accumulating error context on the way
29
  fn append(input: I, kind: ErrorKind, other: Self) -> Self;
30
31
  /// Creates an error from an input position and an expected character
32
29.4M
  fn from_char(input: I, _: char) -> Self {
33
29.4M
    Self::from_error_kind(input, ErrorKind::Char)
34
29.4M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_char
Line
Count
Source
32
9.61M
  fn from_char(input: I, _: char) -> Self {
33
9.61M
    Self::from_error_kind(input, ErrorKind::Char)
34
9.61M
  }
<nom::error::Error<&str> as nom::error::ParseError<&str>>::from_char
Line
Count
Source
32
376k
  fn from_char(input: I, _: char) -> Self {
33
376k
    Self::from_error_kind(input, ErrorKind::Char)
34
376k
  }
<suricata::pgsql::parser::PgsqlParseError<&[u8]> as nom::error::ParseError<&[u8]>>::from_char
Line
Count
Source
32
135k
  fn from_char(input: I, _: char) -> Self {
33
135k
    Self::from_error_kind(input, ErrorKind::Char)
34
135k
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_char
Line
Count
Source
32
19.3M
  fn from_char(input: I, _: char) -> Self {
33
19.3M
    Self::from_error_kind(input, ErrorKind::Char)
34
19.3M
  }
Unexecuted instantiation: <_ as nom::error::ParseError<_>>::from_char
35
36
  /// Combines two existing errors. This function is used to compare errors
37
  /// generated in various branches of `alt`.
38
29.4M
  fn or(self, other: Self) -> Self {
39
29.4M
    other
40
29.4M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::or
Line
Count
Source
38
14.0k
  fn or(self, other: Self) -> Self {
39
14.0k
    other
40
14.0k
  }
<nom::error::Error<&str> as nom::error::ParseError<&str>>::or
Line
Count
Source
38
3.05M
  fn or(self, other: Self) -> Self {
39
3.05M
    other
40
3.05M
  }
<suricata::pgsql::parser::PgsqlParseError<&[u8]> as nom::error::ParseError<&[u8]>>::or
Line
Count
Source
38
95.3k
  fn or(self, other: Self) -> Self {
39
95.3k
    other
40
95.3k
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::or
Line
Count
Source
38
26.2M
  fn or(self, other: Self) -> Self {
39
26.2M
    other
40
26.2M
  }
Unexecuted instantiation: <_ as nom::error::ParseError<_>>::or
41
}
42
43
/// This trait is required by the `context` combinator to add a static string
44
/// to an existing error
45
pub trait ContextError<I>: Sized {
46
  /// Creates a new error from an input position, a static string and an existing error.
47
  /// This is used mainly in the [context] combinator, to add user friendly information
48
  /// to errors when backtracking through a parse tree
49
0
  fn add_context(_input: I, _ctx: &'static str, other: Self) -> Self {
50
0
    other
51
0
  }
52
}
53
54
/// This trait is required by the `map_res` combinator to integrate
55
/// error types from external functions, like [std::str::FromStr]
56
pub trait FromExternalError<I, E> {
57
  /// Creates a new error from an input position, an [ErrorKind] indicating the
58
  /// wrapping parser, and an external error
59
  fn from_external_error(input: I, kind: ErrorKind, e: E) -> Self;
60
}
61
62
/// default error type, only contains the error's location and code
63
#[derive(Clone, Debug, Eq, PartialEq)]
64
pub struct Error<I> {
65
  /// position of the error in the input data
66
  pub input: I,
67
  /// nom error code
68
  pub code: ErrorKind,
69
}
70
71
impl<I> Error<I> {
72
  /// creates a new basic error
73
0
  pub fn new(input: I, code: ErrorKind) -> Error<I> {
74
0
    Error { input, code }
75
0
  }
76
}
77
78
impl<I> ParseError<I> for Error<I> {
79
113M
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
80
113M
    Error { input, code: kind }
81
113M
  }
<nom::error::Error<(&[u8], usize)> as nom::error::ParseError<(&[u8], usize)>>::from_error_kind
Line
Count
Source
79
3.35k
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
80
3.35k
    Error { input, code: kind }
81
3.35k
  }
<nom::error::Error<&str> as nom::error::ParseError<&str>>::from_error_kind
Line
Count
Source
79
6.82M
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
80
6.82M
    Error { input, code: kind }
81
6.82M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_error_kind
Line
Count
Source
79
14.7M
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
80
14.7M
    Error { input, code: kind }
81
14.7M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_error_kind
Line
Count
Source
79
92.1M
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
80
92.1M
    Error { input, code: kind }
81
92.1M
  }
Unexecuted instantiation: <nom::error::Error<_> as nom::error::ParseError<_>>::from_error_kind
82
83
18.2M
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
84
18.2M
    other
85
18.2M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::append
Line
Count
Source
83
65.0k
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
84
65.0k
    other
85
65.0k
  }
<nom::error::Error<&str> as nom::error::ParseError<&str>>::append
Line
Count
Source
83
1.04M
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
84
1.04M
    other
85
1.04M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::append
Line
Count
Source
83
17.1M
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
84
17.1M
    other
85
17.1M
  }
Unexecuted instantiation: <nom::error::Error<_> as nom::error::ParseError<_>>::append
86
}
87
88
impl<I> ContextError<I> for Error<I> {}
89
90
impl<I, E> FromExternalError<I, E> for Error<I> {
91
  /// Create a new error from an input position and an external error
92
63.5k
  fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
93
63.5k
    Error { input, code: kind }
94
63.5k
  }
<nom::error::Error<&[u8]> as nom::error::FromExternalError<&[u8], alloc::boxed::Box<dyn core::error::Error>>>::from_external_error
Line
Count
Source
92
530
  fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
93
530
    Error { input, code: kind }
94
530
  }
Unexecuted instantiation: <nom::error::Error<&[u8]> as nom::error::FromExternalError<&[u8], alloc::string::FromUtf8Error>>::from_external_error
<nom::error::Error<&[u8]> as nom::error::FromExternalError<&[u8], core::net::parser::AddrParseError>>::from_external_error
Line
Count
Source
92
952
  fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
93
952
    Error { input, code: kind }
94
952
  }
<nom::error::Error<&[u8]> as nom::error::FromExternalError<&[u8], core::num::error::ParseIntError>>::from_external_error
Line
Count
Source
92
52.5k
  fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
93
52.5k
    Error { input, code: kind }
94
52.5k
  }
<nom::error::Error<&[u8]> as nom::error::FromExternalError<&[u8], core::str::error::Utf8Error>>::from_external_error
Line
Count
Source
92
1.83k
  fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
93
1.83k
    Error { input, code: kind }
94
1.83k
  }
<nom::error::Error<&str> as nom::error::FromExternalError<&str, alloc::string::String>>::from_external_error
Line
Count
Source
92
4.63k
  fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
93
4.63k
    Error { input, code: kind }
94
4.63k
  }
<nom::error::Error<&str> as nom::error::FromExternalError<&str, core::num::error::ParseIntError>>::from_external_error
Line
Count
Source
92
3.05k
  fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
93
3.05k
    Error { input, code: kind }
94
3.05k
  }
Unexecuted instantiation: <nom::error::Error<_> as nom::error::FromExternalError<_, _>>::from_external_error
95
}
96
97
/// The Display implementation allows the std::error::Error implementation
98
impl<I: fmt::Display> fmt::Display for Error<I> {
99
0
  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
100
0
    write!(f, "error {:?} at: {}", self.code, self.input)
101
0
  }
102
}
103
104
#[cfg(feature = "alloc")]
105
impl<I: ToOwned + ?Sized> Error<&I> {
106
  /// Converts `Error<&I>` into `Error<I::Owned>` by cloning.
107
0
  pub fn cloned(self) -> Error<I::Owned> {
108
0
    Error {
109
0
      input: self.input.to_owned(),
110
0
      code: self.code,
111
0
    }
112
0
  }
113
}
114
115
#[cfg(feature = "alloc")]
116
impl<I: ToOwned + ?Sized> Error<&mut I> {
117
  /// Converts `Error<&mut I>` into `Error<I::Owned>` by cloning.
118
0
  pub fn cloned(self) -> Error<I::Owned> {
119
0
    Error {
120
0
      input: self.input.to_owned(),
121
0
      code: self.code,
122
0
    }
123
0
  }
124
}
125
126
impl<I: Copy> Error<&I> {
127
  /// Converts `Error<&I>` into `Error<I>` by copying.
128
0
  pub fn copied(self) -> Error<I> {
129
0
    Error {
130
0
      input: *self.input,
131
0
      code: self.code,
132
0
    }
133
0
  }
134
}
135
136
impl<I: Copy> Error<&mut I> {
137
  /// Converts `Error<&mut I>` into `Error<I>` by copying.
138
0
  pub fn copied(self) -> Error<I> {
139
0
    Error {
140
0
      input: *self.input,
141
0
      code: self.code,
142
0
    }
143
0
  }
144
}
145
146
#[cfg(feature = "std")]
147
impl<I: fmt::Debug + fmt::Display> std::error::Error for Error<I> {}
148
149
#[cfg(feature = "alloc")]
150
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
151
impl From<Error<&[u8]>> for Error<crate::lib::std::vec::Vec<u8>> {
152
0
  fn from(value: Error<&[u8]>) -> Self {
153
0
    Error {
154
0
      input: value.input.to_owned(),
155
0
      code: value.code,
156
0
    }
157
0
  }
158
}
159
160
#[cfg(feature = "alloc")]
161
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "alloc")))]
162
impl From<Error<&str>> for Error<crate::lib::std::string::String> {
163
0
  fn from(value: Error<&str>) -> Self {
164
0
    Error {
165
0
      input: value.input.to_owned(),
166
0
      code: value.code,
167
0
    }
168
0
  }
169
}
170
171
// for backward compatibility, keep those trait implementations
172
// for the previously used error type
173
impl<I> ParseError<I> for (I, ErrorKind) {
174
0
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
175
0
    (input, kind)
176
0
  }
177
178
0
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
179
0
    other
180
0
  }
181
}
182
183
impl<I> ContextError<I> for (I, ErrorKind) {}
184
185
impl<I, E> FromExternalError<I, E> for (I, ErrorKind) {
186
0
  fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
187
0
    (input, kind)
188
0
  }
189
}
190
191
impl<I> ParseError<I> for () {
192
13.3k
  fn from_error_kind(_: I, _: ErrorKind) -> Self {}
<() as nom::error::ParseError<&[u8]>>::from_error_kind
Line
Count
Source
192
13.3k
  fn from_error_kind(_: I, _: ErrorKind) -> Self {}
Unexecuted instantiation: <() as nom::error::ParseError<_>>::from_error_kind
193
194
0
  fn append(_: I, _: ErrorKind, _: Self) -> Self {}
195
}
196
197
impl<I> ContextError<I> for () {}
198
199
impl<I, E> FromExternalError<I, E> for () {
200
0
  fn from_external_error(_input: I, _kind: ErrorKind, _e: E) -> Self {}
201
}
202
203
/// Creates an error from the input position and an [ErrorKind]
204
1.75M
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
205
1.75M
  E::from_error_kind(input, kind)
206
1.75M
}
nom::error::make_error::<&[u8], nom::error::Error<&[u8]>>
Line
Count
Source
204
301k
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
205
301k
  E::from_error_kind(input, kind)
206
301k
}
nom::error::make_error::<&[u8], suricata::rdp::error::RdpError>
Line
Count
Source
204
1.00M
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
205
1.00M
  E::from_error_kind(input, kind)
206
1.00M
}
Unexecuted instantiation: nom::error::make_error::<&[u8], suricata::smb::error::SmbError>
nom::error::make_error::<&[u8], suricata::pgsql::parser::PgsqlParseError<&[u8]>>
Line
Count
Source
204
38.5k
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
205
38.5k
  E::from_error_kind(input, kind)
206
38.5k
}
nom::error::make_error::<&str, nom::error::Error<&str>>
Line
Count
Source
204
7.98k
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
205
7.98k
  E::from_error_kind(input, kind)
206
7.98k
}
Unexecuted instantiation: nom::error::make_error::<_, _>
nom::error::make_error::<&[u8], nom::error::Error<&[u8]>>
Line
Count
Source
204
402k
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
205
402k
  E::from_error_kind(input, kind)
206
402k
}
207
208
/// Combines an existing error with a new one created from the input
209
/// position and an [ErrorKind]. This is useful when backtracking
210
/// through a parse tree, accumulating error context on the way
211
0
pub fn append_error<I, E: ParseError<I>>(input: I, kind: ErrorKind, other: E) -> E {
212
0
  E::append(input, kind, other)
213
0
}
214
215
/// Create a new error from an input position, a static string and an existing error.
216
/// This is used mainly in the [context] combinator, to add user friendly information
217
/// to errors when backtracking through a parse tree
218
0
pub fn context<F>(context: &'static str, parser: F) -> Context<F> {
219
0
  Context { context, parser }
220
0
}
221
222
/// Parser implementation for [context]
223
pub struct Context<F> {
224
  context: &'static str,
225
  parser: F,
226
}
227
228
impl<I, F> Parser<I> for Context<F>
229
where
230
  I: Clone,
231
  F: Parser<I>,
232
  <F as Parser<I>>::Error: ContextError<I>,
233
{
234
  type Output = <F as Parser<I>>::Output;
235
  type Error = <F as Parser<I>>::Error;
236
237
0
  fn process<OM: OutputMode>(&mut self, input: I) -> PResult<OM, I, Self::Output, Self::Error> {
238
0
    match self.parser.process::<OM>(input.clone()) {
239
0
      Err(Err::Error(e)) => Err(Err::Error(OM::Error::map(e, |e| {
240
0
        <F as Parser<I>>::Error::add_context(input, self.context, e)
241
0
      }))),
242
0
      Err(Err::Failure(e)) => Err(Err::Failure(<F as Parser<I>>::Error::add_context(
243
0
        input,
244
0
        self.context,
245
0
        e,
246
0
      ))),
247
0
      x => x,
248
    }
249
0
  }
250
}
251
252
/// Indicates which parser returned an error
253
#[rustfmt::skip]
254
#[derive(Debug,PartialEq,Eq,Hash,Clone,Copy)]
255
#[allow(deprecated,missing_docs)]
256
pub enum ErrorKind {
257
  Tag,
258
  MapRes,
259
  MapOpt,
260
  Alt,
261
  IsNot,
262
  IsA,
263
  SeparatedList,
264
  SeparatedNonEmptyList,
265
  Many0,
266
  Many1,
267
  ManyTill,
268
  Count,
269
  TakeUntil,
270
  LengthValue,
271
  TagClosure,
272
  Alpha,
273
  Digit,
274
  HexDigit,
275
  OctDigit,
276
  BinDigit,
277
  AlphaNumeric,
278
  Space,
279
  MultiSpace,
280
  LengthValueFn,
281
  Eof,
282
  Switch,
283
  TagBits,
284
  OneOf,
285
  NoneOf,
286
  Char,
287
  CrLf,
288
  RegexpMatch,
289
  RegexpMatches,
290
  RegexpFind,
291
  RegexpCapture,
292
  RegexpCaptures,
293
  TakeWhile1,
294
  Complete,
295
  Fix,
296
  Escaped,
297
  EscapedTransform,
298
  NonEmpty,
299
  ManyMN,
300
  Not,
301
  Permutation,
302
  Verify,
303
  TakeTill1,
304
  TakeWhileMN,
305
  TooLarge,
306
  Many0Count,
307
  Many1Count,
308
  Float,
309
  Satisfy,
310
  Fail,
311
  Many,
312
  Fold,
313
  Precedence,
314
}
315
316
#[rustfmt::skip]
317
#[allow(deprecated)]
318
/// Converts an ErrorKind to a number
319
0
pub fn error_to_u32(e: &ErrorKind) -> u32 {
320
0
  match *e {
321
0
    ErrorKind::Tag                       => 1,
322
0
    ErrorKind::MapRes                    => 2,
323
0
    ErrorKind::MapOpt                    => 3,
324
0
    ErrorKind::Alt                       => 4,
325
0
    ErrorKind::IsNot                     => 5,
326
0
    ErrorKind::IsA                       => 6,
327
0
    ErrorKind::SeparatedList             => 7,
328
0
    ErrorKind::SeparatedNonEmptyList     => 8,
329
0
    ErrorKind::Many1                     => 9,
330
0
    ErrorKind::Count                     => 10,
331
0
    ErrorKind::TakeUntil                 => 12,
332
0
    ErrorKind::LengthValue               => 15,
333
0
    ErrorKind::TagClosure                => 16,
334
0
    ErrorKind::Alpha                     => 17,
335
0
    ErrorKind::Digit                     => 18,
336
0
    ErrorKind::AlphaNumeric              => 19,
337
0
    ErrorKind::Space                     => 20,
338
0
    ErrorKind::MultiSpace                => 21,
339
0
    ErrorKind::LengthValueFn             => 22,
340
0
    ErrorKind::Eof                       => 23,
341
0
    ErrorKind::Switch                    => 27,
342
0
    ErrorKind::TagBits                   => 28,
343
0
    ErrorKind::OneOf                     => 29,
344
0
    ErrorKind::NoneOf                    => 30,
345
0
    ErrorKind::Char                      => 40,
346
0
    ErrorKind::CrLf                      => 41,
347
0
    ErrorKind::RegexpMatch               => 42,
348
0
    ErrorKind::RegexpMatches             => 43,
349
0
    ErrorKind::RegexpFind                => 44,
350
0
    ErrorKind::RegexpCapture             => 45,
351
0
    ErrorKind::RegexpCaptures            => 46,
352
0
    ErrorKind::TakeWhile1                => 47,
353
0
    ErrorKind::Complete                  => 48,
354
0
    ErrorKind::Fix                       => 49,
355
0
    ErrorKind::Escaped                   => 50,
356
0
    ErrorKind::EscapedTransform          => 51,
357
0
    ErrorKind::NonEmpty                  => 56,
358
0
    ErrorKind::ManyMN                    => 57,
359
0
    ErrorKind::HexDigit                  => 59,
360
0
    ErrorKind::OctDigit                  => 61,
361
0
    ErrorKind::Many0                     => 62,
362
0
    ErrorKind::Not                       => 63,
363
0
    ErrorKind::Permutation               => 64,
364
0
    ErrorKind::ManyTill                  => 65,
365
0
    ErrorKind::Verify                    => 66,
366
0
    ErrorKind::TakeTill1                 => 67,
367
0
    ErrorKind::TakeWhileMN               => 69,
368
0
    ErrorKind::TooLarge                  => 70,
369
0
    ErrorKind::Many0Count                => 71,
370
0
    ErrorKind::Many1Count                => 72,
371
0
    ErrorKind::Float                     => 73,
372
0
    ErrorKind::Satisfy                   => 74,
373
0
    ErrorKind::Fail                      => 75,
374
0
    ErrorKind::Many                      => 76,
375
0
    ErrorKind::Fold                      => 77,
376
0
    ErrorKind::BinDigit                  => 78,
377
0
    ErrorKind::Precedence                => 79,
378
  }
379
0
}
380
381
impl ErrorKind {
382
  #[rustfmt::skip]
383
  #[allow(deprecated)]
384
  /// Converts an ErrorKind to a text description
385
0
  pub fn description(&self) -> &str {
386
0
    match *self {
387
0
      ErrorKind::Tag                       => "Tag",
388
0
      ErrorKind::MapRes                    => "Map on Result",
389
0
      ErrorKind::MapOpt                    => "Map on Option",
390
0
      ErrorKind::Alt                       => "Alternative",
391
0
      ErrorKind::IsNot                     => "IsNot",
392
0
      ErrorKind::IsA                       => "IsA",
393
0
      ErrorKind::SeparatedList             => "Separated list",
394
0
      ErrorKind::SeparatedNonEmptyList     => "Separated non empty list",
395
0
      ErrorKind::Many0                     => "Many0",
396
0
      ErrorKind::Many1                     => "Many1",
397
0
      ErrorKind::Count                     => "Count",
398
0
      ErrorKind::TakeUntil                 => "Take until",
399
0
      ErrorKind::LengthValue               => "Length followed by value",
400
0
      ErrorKind::TagClosure                => "Tag closure",
401
0
      ErrorKind::Alpha                     => "Alphabetic",
402
0
      ErrorKind::Digit                     => "Digit",
403
0
      ErrorKind::AlphaNumeric              => "AlphaNumeric",
404
0
      ErrorKind::Space                     => "Space",
405
0
      ErrorKind::MultiSpace                => "Multiple spaces",
406
0
      ErrorKind::LengthValueFn             => "LengthValueFn",
407
0
      ErrorKind::Eof                       => "End of file",
408
0
      ErrorKind::Switch                    => "Switch",
409
0
      ErrorKind::TagBits                   => "Tag on bitstream",
410
0
      ErrorKind::OneOf                     => "OneOf",
411
0
      ErrorKind::NoneOf                    => "NoneOf",
412
0
      ErrorKind::Char                      => "Char",
413
0
      ErrorKind::CrLf                      => "CrLf",
414
0
      ErrorKind::RegexpMatch               => "RegexpMatch",
415
0
      ErrorKind::RegexpMatches             => "RegexpMatches",
416
0
      ErrorKind::RegexpFind                => "RegexpFind",
417
0
      ErrorKind::RegexpCapture             => "RegexpCapture",
418
0
      ErrorKind::RegexpCaptures            => "RegexpCaptures",
419
0
      ErrorKind::TakeWhile1                => "TakeWhile1",
420
0
      ErrorKind::Complete                  => "Complete",
421
0
      ErrorKind::Fix                       => "Fix",
422
0
      ErrorKind::Escaped                   => "Escaped",
423
0
      ErrorKind::EscapedTransform          => "EscapedTransform",
424
0
      ErrorKind::NonEmpty                  => "NonEmpty",
425
0
      ErrorKind::ManyMN                    => "Many(m, n)",
426
0
      ErrorKind::HexDigit                  => "Hexadecimal Digit",
427
0
      ErrorKind::OctDigit                  => "Octal digit",
428
0
      ErrorKind::BinDigit                  => "Binary digit",
429
0
      ErrorKind::Not                       => "Negation",
430
0
      ErrorKind::Permutation               => "Permutation",
431
0
      ErrorKind::ManyTill                  => "ManyTill",
432
0
      ErrorKind::Verify                    => "predicate verification",
433
0
      ErrorKind::TakeTill1                 => "TakeTill1",
434
0
      ErrorKind::TakeWhileMN               => "TakeWhileMN",
435
0
      ErrorKind::TooLarge                  => "Needed data size is too large",
436
0
      ErrorKind::Many0Count                => "Count occurrence of >=0 patterns",
437
0
      ErrorKind::Many1Count                => "Count occurrence of >=1 patterns",
438
0
      ErrorKind::Float                     => "Float",
439
0
      ErrorKind::Satisfy                   => "Satisfy",
440
0
      ErrorKind::Fail                      => "Fail",
441
0
      ErrorKind::Many                      => "Many",
442
0
      ErrorKind::Fold                      => "Fold",
443
0
      ErrorKind::Precedence                => "Precedence",
444
    }
445
0
  }
446
}
447
448
/// Creates a parse error from a `nom::ErrorKind`
449
/// and the position in the input
450
#[allow(unused_variables)]
451
#[macro_export(local_inner_macros)]
452
macro_rules! error_position(
453
  ($input:expr, $code:expr $(,)?) => ({
454
    $crate::error::make_error($input, $code)
455
  });
456
);
457
458
/// Creates a parse error from a `nom::ErrorKind`,
459
/// the position in the input and the next error in
460
/// the parsing tree
461
#[allow(unused_variables)]
462
#[macro_export(local_inner_macros)]
463
macro_rules! error_node_position(
464
  ($input:expr, $code:expr, $next:expr $(,)?) => ({
465
    $crate::error::append_error($input, $code, $next)
466
  });
467
);
468
469
/// Prints a message and the input if the parser fails.
470
///
471
/// The message prints the `Error` or `Incomplete`
472
/// and the parser's calling code.
473
///
474
/// It also displays the input in hexdump format
475
///
476
/// ```rust
477
/// use nom::{IResult, error::dbg_dmp, bytes::complete::tag};
478
///
479
/// fn f(i: &[u8]) -> IResult<&[u8], &[u8]> {
480
///   dbg_dmp(tag("abcd"), "tag")(i)
481
/// }
482
///
483
///   let a = &b"efghijkl"[..];
484
///
485
/// // Will print the following message:
486
/// // Error(Position(0, [101, 102, 103, 104, 105, 106, 107, 108])) at l.5 by ' tag ! ( "abcd" ) '
487
/// // 00000000        65 66 67 68 69 6a 6b 6c         efghijkl
488
/// f(a);
489
/// ```
490
#[cfg(feature = "std")]
491
#[cfg_attr(feature = "docsrs", doc(cfg(feature = "std")))]
492
0
pub fn dbg_dmp<'a, F, O, E: std::fmt::Debug>(
493
0
  f: F,
494
0
  context: &'static str,
495
0
) -> impl Fn(&'a [u8]) -> IResult<&'a [u8], O, E>
496
0
where
497
0
  F: Fn(&'a [u8]) -> IResult<&'a [u8], O, E>,
498
{
499
  use crate::HexDisplay;
500
0
  move |i: &'a [u8]| match f(i) {
501
0
    Err(e) => {
502
0
      println!("{}: Error({:?}) at:\n{}", context, e, i.to_hex(8));
503
0
      Err(e)
504
    }
505
0
    a => a,
506
0
  }
507
0
}
508
509
#[cfg(test)]
510
mod tests {
511
  use super::*;
512
513
  #[test]
514
  fn context_test() {
515
    use crate::{character::char, combinator::cut, internal::Needed};
516
517
    #[derive(Debug, PartialEq)]
518
    struct Error<I> {
519
      input: I,
520
      ctx: Option<&'static str>,
521
    }
522
523
    impl<I> ParseError<I> for Error<I> {
524
      fn from_error_kind(input: I, _kind: ErrorKind) -> Self {
525
        Self { input, ctx: None }
526
      }
527
528
      fn append(input: I, _kind: ErrorKind, other: Self) -> Self {
529
        Self {
530
          input,
531
          ctx: other.ctx,
532
        }
533
      }
534
    }
535
536
    impl<I> ContextError<I> for Error<I> {
537
      fn add_context(input: I, ctx: &'static str, _other: Self) -> Self {
538
        Self {
539
          input,
540
          ctx: Some(ctx),
541
        }
542
      }
543
    }
544
545
    assert_eq!(
546
      context("ctx", char::<_, Error<_>>('a')).parse("abcd"),
547
      Ok(("bcd", 'a'))
548
    );
549
    assert_eq!(
550
      context("ctx", char::<_, Error<_>>('a')).parse(""),
551
      Err(Err::Incomplete(Needed::new(1)))
552
    );
553
    assert_eq!(
554
      context("ctx", char::<_, Error<_>>('a')).parse_complete(""),
555
      Err(Err::Error(Error {
556
        input: "",
557
        ctx: Some("ctx")
558
      }))
559
    );
560
    assert_eq!(
561
      context("ctx", cut(char::<_, Error<_>>('a'))).parse("bcd"),
562
      Err(Err::Failure(Error {
563
        input: "bcd",
564
        ctx: Some("ctx")
565
      }))
566
    );
567
  }
568
569
  #[cfg(feature = "alloc")]
570
  #[test]
571
  fn clone_error() {
572
    use crate::lib::std::string::String;
573
    let err = Error {
574
      code: ErrorKind::Eof,
575
      input: "test",
576
    };
577
578
    let _err: Error<String> = err.cloned();
579
  }
580
581
  #[test]
582
  fn copy_error() {
583
    let err = Error {
584
      code: ErrorKind::Eof,
585
      input: &0_u8,
586
    };
587
588
    let _err: Error<u8> = err.copied();
589
  }
590
}
591
592
/*
593
#[cfg(feature = "alloc")]
594
use lib::std::{vec::Vec, collections::HashMap};
595
596
#[cfg(feature = "std")]
597
use lib::std::hash::Hash;
598
599
#[cfg(feature = "std")]
600
pub fn add_error_pattern<'a, I: Clone + Hash + Eq, O, E: Clone + Hash + Eq>(
601
  h: &mut HashMap<VerboseError<I>, &'a str>,
602
  e: VerboseError<I>,
603
  message: &'a str,
604
) -> bool {
605
  h.insert(e, message);
606
  true
607
}
608
609
pub fn slice_to_offsets(input: &[u8], s: &[u8]) -> (usize, usize) {
610
  let start = input.as_ptr();
611
  let off1 = s.as_ptr() as usize - start as usize;
612
  let off2 = off1 + s.len();
613
  (off1, off2)
614
}
615
616
#[cfg(feature = "std")]
617
pub fn prepare_errors<O, E: Clone>(input: &[u8], e: VerboseError<&[u8]>) -> Option<Vec<(ErrorKind, usize, usize)>> {
618
  let mut v: Vec<(ErrorKind, usize, usize)> = Vec::new();
619
620
  for (p, kind) in e.errors.drain(..) {
621
    let (o1, o2) = slice_to_offsets(input, p);
622
    v.push((kind, o1, o2));
623
  }
624
625
  v.reverse();
626
  Some(v)
627
}
628
629
#[cfg(feature = "std")]
630
pub fn print_error<O, E: Clone>(input: &[u8], res: VerboseError<&[u8]>) {
631
  if let Some(v) = prepare_errors(input, res) {
632
    let colors = generate_colors(&v);
633
    println!("parser codes: {}", print_codes(&colors, &HashMap::new()));
634
    println!("{}", print_offsets(input, 0, &v));
635
  } else {
636
    println!("not an error");
637
  }
638
}
639
640
#[cfg(feature = "std")]
641
pub fn generate_colors<E>(v: &[(ErrorKind, usize, usize)]) -> HashMap<u32, u8> {
642
  let mut h: HashMap<u32, u8> = HashMap::new();
643
  let mut color = 0;
644
645
  for &(ref c, _, _) in v.iter() {
646
    h.insert(error_to_u32(c), color + 31);
647
    color = color + 1 % 7;
648
  }
649
650
  h
651
}
652
653
pub fn code_from_offset(v: &[(ErrorKind, usize, usize)], offset: usize) -> Option<u32> {
654
  let mut acc: Option<(u32, usize, usize)> = None;
655
  for &(ref ek, s, e) in v.iter() {
656
    let c = error_to_u32(ek);
657
    if s <= offset && offset <= e {
658
      if let Some((_, start, end)) = acc {
659
        if start <= s && e <= end {
660
          acc = Some((c, s, e));
661
        }
662
      } else {
663
        acc = Some((c, s, e));
664
      }
665
    }
666
  }
667
  if let Some((code, _, _)) = acc {
668
    return Some(code);
669
  } else {
670
    return None;
671
  }
672
}
673
674
#[cfg(feature = "alloc")]
675
pub fn reset_color(v: &mut Vec<u8>) {
676
  v.push(0x1B);
677
  v.push(b'[');
678
  v.push(0);
679
  v.push(b'm');
680
}
681
682
#[cfg(feature = "alloc")]
683
pub fn write_color(v: &mut Vec<u8>, color: u8) {
684
  v.push(0x1B);
685
  v.push(b'[');
686
  v.push(1);
687
  v.push(b';');
688
  let s = color.to_string();
689
  let bytes = s.as_bytes();
690
  v.extend(bytes.iter().cloned());
691
  v.push(b'm');
692
}
693
694
#[cfg(feature = "std")]
695
#[cfg_attr(feature = "cargo-clippy", allow(implicit_hasher))]
696
pub fn print_codes(colors: &HashMap<u32, u8>, names: &HashMap<u32, &str>) -> String {
697
  let mut v = Vec::new();
698
  for (code, &color) in colors {
699
    if let Some(&s) = names.get(code) {
700
      let bytes = s.as_bytes();
701
      write_color(&mut v, color);
702
      v.extend(bytes.iter().cloned());
703
    } else {
704
      let s = code.to_string();
705
      let bytes = s.as_bytes();
706
      write_color(&mut v, color);
707
      v.extend(bytes.iter().cloned());
708
    }
709
    reset_color(&mut v);
710
    v.push(b' ');
711
  }
712
  reset_color(&mut v);
713
714
  String::from_utf8_lossy(&v[..]).into_owned()
715
}
716
717
#[cfg(feature = "std")]
718
pub fn print_offsets(input: &[u8], from: usize, offsets: &[(ErrorKind, usize, usize)]) -> String {
719
  let mut v = Vec::with_capacity(input.len() * 3);
720
  let mut i = from;
721
  let chunk_size = 8;
722
  let mut current_code: Option<u32> = None;
723
  let mut current_code2: Option<u32> = None;
724
725
  let colors = generate_colors(&offsets);
726
727
  for chunk in input.chunks(chunk_size) {
728
    let s = format!("{:08x}", i);
729
    for &ch in s.as_bytes().iter() {
730
      v.push(ch);
731
    }
732
    v.push(b'\t');
733
734
    let mut k = i;
735
    let mut l = i;
736
    for &byte in chunk {
737
      if let Some(code) = code_from_offset(&offsets, k) {
738
        if let Some(current) = current_code {
739
          if current != code {
740
            reset_color(&mut v);
741
            current_code = Some(code);
742
            if let Some(&color) = colors.get(&code) {
743
              write_color(&mut v, color);
744
            }
745
          }
746
        } else {
747
          current_code = Some(code);
748
          if let Some(&color) = colors.get(&code) {
749
            write_color(&mut v, color);
750
          }
751
        }
752
      }
753
      v.push(CHARS[(byte >> 4) as usize]);
754
      v.push(CHARS[(byte & 0xf) as usize]);
755
      v.push(b' ');
756
      k = k + 1;
757
    }
758
759
    reset_color(&mut v);
760
761
    if chunk_size > chunk.len() {
762
      for _ in 0..(chunk_size - chunk.len()) {
763
        v.push(b' ');
764
        v.push(b' ');
765
        v.push(b' ');
766
      }
767
    }
768
    v.push(b'\t');
769
770
    for &byte in chunk {
771
      if let Some(code) = code_from_offset(&offsets, l) {
772
        if let Some(current) = current_code2 {
773
          if current != code {
774
            reset_color(&mut v);
775
            current_code2 = Some(code);
776
            if let Some(&color) = colors.get(&code) {
777
              write_color(&mut v, color);
778
            }
779
          }
780
        } else {
781
          current_code2 = Some(code);
782
          if let Some(&color) = colors.get(&code) {
783
            write_color(&mut v, color);
784
          }
785
        }
786
      }
787
      if (byte >= 32 && byte <= 126) || byte >= 128 {
788
        v.push(byte);
789
      } else {
790
        v.push(b'.');
791
      }
792
      l = l + 1;
793
    }
794
    reset_color(&mut v);
795
796
    v.push(b'\n');
797
    i = i + chunk_size;
798
  }
799
800
  String::from_utf8_lossy(&v[..]).into_owned()
801
}
802
*/