Coverage Report

Created: 2026-06-30 07:20

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