Coverage Report

Created: 2026-03-31 07:45

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
34.2M
  fn from_char(input: I, _: char) -> Self {
27
34.2M
    Self::from_error_kind(input, ErrorKind::Char)
28
34.2M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_char
Line
Count
Source
26
200k
  fn from_char(input: I, _: char) -> Self {
27
200k
    Self::from_error_kind(input, ErrorKind::Char)
28
200k
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_char
Line
Count
Source
26
33.4M
  fn from_char(input: I, _: char) -> Self {
27
33.4M
    Self::from_error_kind(input, ErrorKind::Char)
28
33.4M
  }
Unexecuted instantiation: <_ as nom::error::ParseError<_>>::from_char
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_char
Line
Count
Source
26
532k
  fn from_char(input: I, _: char) -> Self {
27
532k
    Self::from_error_kind(input, ErrorKind::Char)
28
532k
  }
<nom::error::Error<&str> as nom::error::ParseError<&str>>::from_char
Line
Count
Source
26
8.43k
  fn from_char(input: I, _: char) -> Self {
27
8.43k
    Self::from_error_kind(input, ErrorKind::Char)
28
8.43k
  }
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
76.9M
  fn or(self, other: Self) -> Self {
33
76.9M
    other
34
76.9M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::or
Line
Count
Source
32
15.6k
  fn or(self, other: Self) -> Self {
33
15.6k
    other
34
15.6k
  }
<nom::error::Error<(&[u8], usize)> as nom::error::ParseError<(&[u8], usize)>>::or
Line
Count
Source
32
47.9M
  fn or(self, other: Self) -> Self {
33
47.9M
    other
34
47.9M
  }
<asn1_rs::error::Error as nom::error::ParseError<&[u8]>>::or
Line
Count
Source
32
160
  fn or(self, other: Self) -> Self {
33
160
    other
34
160
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::or
Line
Count
Source
32
27.4k
  fn or(self, other: Self) -> Self {
33
27.4k
    other
34
27.4k
  }
Unexecuted instantiation: <_ as nom::error::ParseError<_>>::or
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::or
Line
Count
Source
32
768k
  fn or(self, other: Self) -> Self {
33
768k
    other
34
768k
  }
<nom::error::Error<&str> as nom::error::ParseError<&str>>::or
Line
Count
Source
32
523k
  fn or(self, other: Self) -> Self {
33
523k
    other
34
523k
  }
<nom::error::Error<(&[u8], usize)> as nom::error::ParseError<(&[u8], usize)>>::or
Line
Count
Source
32
27.6M
  fn or(self, other: Self) -> Self {
33
27.6M
    other
34
27.6M
  }
<asn1_rs::error::Error as nom::error::ParseError<&[u8]>>::or
Line
Count
Source
32
143
  fn or(self, other: Self) -> Self {
33
143
    other
34
143
  }
<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
183M
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
183M
    Error { input, code: kind }
75
183M
  }
<nom::error::Error<(&[u8], usize)> as nom::error::ParseError<(&[u8], usize)>>::from_error_kind
Line
Count
Source
73
79.6M
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
79.6M
    Error { input, code: kind }
75
79.6M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_error_kind
Line
Count
Source
73
1.50M
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
1.50M
    Error { input, code: kind }
75
1.50M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_error_kind
Line
Count
Source
73
33.8M
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
33.8M
    Error { input, code: kind }
75
33.8M
  }
<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
144k
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
144k
    Error { input, code: kind }
75
144k
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_error_kind
Line
Count
Source
73
533k
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
533k
    Error { input, code: kind }
75
533k
  }
Unexecuted instantiation: <nom::error::Error<_> as nom::error::ParseError<_>>::from_error_kind
<nom::error::Error<(&[u8], usize)> as nom::error::ParseError<(&[u8], usize)>>::from_error_kind
Line
Count
Source
73
45.7M
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
45.7M
    Error { input, code: kind }
75
45.7M
  }
<nom::error::Error<&str> as nom::error::ParseError<&str>>::from_error_kind
Line
Count
Source
73
1.56M
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
1.56M
    Error { input, code: kind }
75
1.56M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_error_kind
Line
Count
Source
73
19.9M
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
19.9M
    Error { input, code: kind }
75
19.9M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_error_kind
Line
Count
Source
73
44.6k
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
44.6k
    Error { input, code: kind }
75
44.6k
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_error_kind
Line
Count
Source
73
115k
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
115k
    Error { input, code: kind }
75
115k
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_error_kind
Line
Count
Source
73
461k
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
461k
    Error { input, code: kind }
75
461k
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_error_kind
Line
Count
Source
73
512
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
512
    Error { input, code: kind }
75
512
  }
Unexecuted instantiation: <nom::error::Error<_> as nom::error::ParseError<_>>::from_error_kind
76
77
3.88M
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
3.88M
    other
79
3.88M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::append
Line
Count
Source
77
37.5k
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
37.5k
    other
79
37.5k
  }
<nom::error::Error<(&[u8], usize)> as nom::error::ParseError<(&[u8], usize)>>::append
Line
Count
Source
77
2.12M
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
2.12M
    other
79
2.12M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::append
Line
Count
Source
77
283k
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
283k
    other
79
283k
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::append
Line
Count
Source
77
152
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
152
    other
79
152
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::append
Line
Count
Source
77
11.4k
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
11.4k
    other
79
11.4k
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::append
Line
Count
Source
77
27.9k
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
27.9k
    other
79
27.9k
  }
Unexecuted instantiation: <nom::error::Error<_> as nom::error::ParseError<_>>::append
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::append
Line
Count
Source
77
304k
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
304k
    other
79
304k
  }
<nom::error::Error<&str> as nom::error::ParseError<&str>>::append
Line
Count
Source
77
190k
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
190k
    other
79
190k
  }
<nom::error::Error<(&[u8], usize)> as nom::error::ParseError<(&[u8], usize)>>::append
Line
Count
Source
77
881k
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
881k
    other
79
881k
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::append
Line
Count
Source
77
177
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
177
    other
79
177
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::append
Line
Count
Source
77
15.4k
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
15.4k
    other
79
15.4k
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::append
Line
Count
Source
77
4.28k
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
4.28k
    other
79
4.28k
  }
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.1k
  fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
87
14.1k
    Error { input, code: kind }
88
14.1k
  }
<nom::error::Error<&[u8]> as nom::error::FromExternalError<&[u8], core::num::error::ParseIntError>>::from_external_error
Line
Count
Source
86
1.44k
  fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
87
1.44k
    Error { input, code: kind }
88
1.44k
  }
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
4.75k
  fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
87
4.75k
    Error { input, code: kind }
88
4.75k
  }
<nom::error::Error<&[u8]> as nom::error::FromExternalError<&[u8], core::str::error::Utf8Error>>::from_external_error
Line
Count
Source
86
349
  fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
87
349
    Error { input, code: kind }
88
349
  }
<nom::error::Error<&str> as nom::error::FromExternalError<&str, alloc::string::String>>::from_external_error
Line
Count
Source
86
2.85k
  fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
87
2.85k
    Error { input, code: kind }
88
2.85k
  }
<nom::error::Error<&str> as nom::error::FromExternalError<&str, core::num::error::ParseIntError>>::from_external_error
Line
Count
Source
86
3.59k
  fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
87
3.59k
    Error { input, code: kind }
88
3.59k
  }
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.64k
  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.64k
  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
4.86M
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
4.86M
  E::from_error_kind(input, kind)
136
4.86M
}
nom::error::make_error::<(&[u8], usize), nom::error::Error<(&[u8], usize)>>
Line
Count
Source
134
1.06M
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
1.06M
  E::from_error_kind(input, kind)
136
1.06M
}
nom::error::make_error::<&[u8], nom::error::Error<&[u8]>>
Line
Count
Source
134
173k
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
173k
  E::from_error_kind(input, kind)
136
173k
}
nom::error::make_error::<&[u8], nom::error::Error<&[u8]>>
Line
Count
Source
134
17
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
17
  E::from_error_kind(input, kind)
136
17
}
nom::error::make_error::<&[u8], nom::error::Error<&[u8]>>
Line
Count
Source
134
10.7k
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
10.7k
  E::from_error_kind(input, kind)
136
10.7k
}
nom::error::make_error::<&[u8], nom::error::Error<&[u8]>>
Line
Count
Source
134
4.29k
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
4.29k
  E::from_error_kind(input, kind)
136
4.29k
}
Unexecuted instantiation: nom::error::make_error::<_, _>
nom::error::make_error::<(&[u8], usize), nom::error::Error<(&[u8], usize)>>
Line
Count
Source
134
440k
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
440k
  E::from_error_kind(input, kind)
136
440k
}
nom::error::make_error::<&str, nom::error::Error<&str>>
Line
Count
Source
134
2.86k
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
2.86k
  E::from_error_kind(input, kind)
136
2.86k
}
nom::error::make_error::<&[u8], suricata::rdp::error::RdpError>
Line
Count
Source
134
1.31M
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
1.31M
  E::from_error_kind(input, kind)
136
1.31M
}
nom::error::make_error::<&[u8], suricata::quic::error::QuicError>
Line
Count
Source
134
1.49M
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
1.49M
  E::from_error_kind(input, kind)
136
1.49M
}
nom::error::make_error::<&[u8], nom::error::Error<&[u8]>>
Line
Count
Source
134
342k
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
342k
  E::from_error_kind(input, kind)
136
342k
}
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
12.5k
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
12.5k
  E::from_error_kind(input, kind)
136
12.5k
}
nom::error::make_error::<&[u8], nom::error::Error<&[u8]>>
Line
Count
Source
134
6.11k
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
6.11k
  E::from_error_kind(input, kind)
136
6.11k
}
nom::error::make_error::<&[u8], der_parser::error::BerError>
Line
Count
Source
134
471
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
471
  E::from_error_kind(input, kind)
136
471
}
nom::error::make_error::<&[u8], nom::error::Error<&[u8]>>
Line
Count
Source
134
512
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
512
  E::from_error_kind(input, kind)
136
512
}
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
*/