Coverage Report

Created: 2025-11-16 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/nom-7.1.3/src/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
46.5M
  fn from_char(input: I, _: char) -> Self {
27
46.5M
    Self::from_error_kind(input, ErrorKind::Char)
28
46.5M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_char
Line
Count
Source
26
147k
  fn from_char(input: I, _: char) -> Self {
27
147k
    Self::from_error_kind(input, ErrorKind::Char)
28
147k
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_char
Line
Count
Source
26
46.0M
  fn from_char(input: I, _: char) -> Self {
27
46.0M
    Self::from_error_kind(input, ErrorKind::Char)
28
46.0M
  }
Unexecuted instantiation: <_ as nom::error::ParseError<_>>::from_char
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_char
Line
Count
Source
26
377k
  fn from_char(input: I, _: char) -> Self {
27
377k
    Self::from_error_kind(input, ErrorKind::Char)
28
377k
  }
<nom::error::Error<&str> as nom::error::ParseError<&str>>::from_char
Line
Count
Source
26
3.13k
  fn from_char(input: I, _: char) -> Self {
27
3.13k
    Self::from_error_kind(input, ErrorKind::Char)
28
3.13k
  }
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
90.9M
  fn or(self, other: Self) -> Self {
33
90.9M
    other
34
90.9M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::or
Line
Count
Source
32
13.2k
  fn or(self, other: Self) -> Self {
33
13.2k
    other
34
13.2k
  }
<nom::error::Error<(&[u8], usize)> as nom::error::ParseError<(&[u8], usize)>>::or
Line
Count
Source
32
55.8M
  fn or(self, other: Self) -> Self {
33
55.8M
    other
34
55.8M
  }
<asn1_rs::error::Error as nom::error::ParseError<&[u8]>>::or
Line
Count
Source
32
125
  fn or(self, other: Self) -> Self {
33
125
    other
34
125
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::or
Line
Count
Source
32
87.0k
  fn or(self, other: Self) -> Self {
33
87.0k
    other
34
87.0k
  }
Unexecuted instantiation: <_ as nom::error::ParseError<_>>::or
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::or
Line
Count
Source
32
558k
  fn or(self, other: Self) -> Self {
33
558k
    other
34
558k
  }
<nom::error::Error<&str> as nom::error::ParseError<&str>>::or
Line
Count
Source
32
245k
  fn or(self, other: Self) -> Self {
33
245k
    other
34
245k
  }
<nom::error::Error<(&[u8], usize)> as nom::error::ParseError<(&[u8], usize)>>::or
Line
Count
Source
32
34.1M
  fn or(self, other: Self) -> Self {
33
34.1M
    other
34
34.1M
  }
<asn1_rs::error::Error as nom::error::ParseError<&[u8]>>::or
Line
Count
Source
32
126
  fn or(self, other: Self) -> Self {
33
126
    other
34
126
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::or
Line
Count
Source
32
3.37k
  fn or(self, other: Self) -> Self {
33
3.37k
    other
34
3.37k
  }
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
210M
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
210M
    Error { input, code: kind }
75
210M
  }
<nom::error::Error<(&[u8], usize)> as nom::error::ParseError<(&[u8], usize)>>::from_error_kind
Line
Count
Source
73
86.5M
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
86.5M
    Error { input, code: kind }
75
86.5M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_error_kind
Line
Count
Source
73
1.52M
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
1.52M
    Error { input, code: kind }
75
1.52M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_error_kind
Line
Count
Source
73
46.4M
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
46.4M
    Error { input, code: kind }
75
46.4M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_error_kind
Line
Count
Source
73
41.0k
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
41.0k
    Error { input, code: kind }
75
41.0k
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_error_kind
Line
Count
Source
73
124k
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
124k
    Error { input, code: kind }
75
124k
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_error_kind
Line
Count
Source
73
777k
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
777k
    Error { input, code: kind }
75
777k
  }
Unexecuted instantiation: <nom::error::Error<_> as nom::error::ParseError<_>>::from_error_kind
<nom::error::Error<&str> as nom::error::ParseError<&str>>::from_error_kind
Line
Count
Source
73
673k
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
673k
    Error { input, code: kind }
75
673k
  }
<nom::error::Error<(&[u8], usize)> as nom::error::ParseError<(&[u8], usize)>>::from_error_kind
Line
Count
Source
73
57.6M
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
57.6M
    Error { input, code: kind }
75
57.6M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_error_kind
Line
Count
Source
73
16.0M
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
16.0M
    Error { input, code: kind }
75
16.0M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_error_kind
Line
Count
Source
73
39.0k
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
39.0k
    Error { input, code: kind }
75
39.0k
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_error_kind
Line
Count
Source
73
147k
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
147k
    Error { input, code: kind }
75
147k
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_error_kind
Line
Count
Source
73
514k
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
514k
    Error { input, code: kind }
75
514k
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::from_error_kind
Line
Count
Source
73
756
  fn from_error_kind(input: I, kind: ErrorKind) -> Self {
74
756
    Error { input, code: kind }
75
756
  }
Unexecuted instantiation: <nom::error::Error<_> as nom::error::ParseError<_>>::from_error_kind
76
77
4.78M
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
4.78M
    other
79
4.78M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::append
Line
Count
Source
77
34.1k
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
34.1k
    other
79
34.1k
  }
<nom::error::Error<(&[u8], usize)> as nom::error::ParseError<(&[u8], usize)>>::append
Line
Count
Source
77
3.01M
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
3.01M
    other
79
3.01M
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::append
Line
Count
Source
77
371k
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
371k
    other
79
371k
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::append
Line
Count
Source
77
142
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
142
    other
79
142
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::append
Line
Count
Source
77
12.6k
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
12.6k
    other
79
12.6k
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::append
Line
Count
Source
77
87.5k
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
87.5k
    other
79
87.5k
  }
Unexecuted instantiation: <nom::error::Error<_> as nom::error::ParseError<_>>::append
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::append
Line
Count
Source
77
232k
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
232k
    other
79
232k
  }
<nom::error::Error<&str> as nom::error::ParseError<&str>>::append
Line
Count
Source
77
89.4k
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
89.4k
    other
79
89.4k
  }
<nom::error::Error<(&[u8], usize)> as nom::error::ParseError<(&[u8], usize)>>::append
Line
Count
Source
77
925k
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
925k
    other
79
925k
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::append
Line
Count
Source
77
132
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
132
    other
79
132
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::append
Line
Count
Source
77
17.4k
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
17.4k
    other
79
17.4k
  }
<nom::error::Error<&[u8]> as nom::error::ParseError<&[u8]>>::append
Line
Count
Source
77
3.77k
  fn append(_: I, _: ErrorKind, other: Self) -> Self {
78
3.77k
    other
79
3.77k
  }
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
10.5k
  fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
87
10.5k
    Error { input, code: kind }
88
10.5k
  }
<nom::error::Error<&[u8]> as nom::error::FromExternalError<&[u8], core::num::error::ParseIntError>>::from_external_error
Line
Count
Source
86
1.10k
  fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
87
1.10k
    Error { input, code: kind }
88
1.10k
  }
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.00k
  fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
87
1.00k
    Error { input, code: kind }
88
1.00k
  }
<nom::error::Error<&[u8]> as nom::error::FromExternalError<&[u8], core::num::error::ParseIntError>>::from_external_error
Line
Count
Source
86
4.70k
  fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
87
4.70k
    Error { input, code: kind }
88
4.70k
  }
<nom::error::Error<&[u8]> as nom::error::FromExternalError<&[u8], core::str::error::Utf8Error>>::from_external_error
Line
Count
Source
86
318
  fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
87
318
    Error { input, code: kind }
88
318
  }
<nom::error::Error<&str> as nom::error::FromExternalError<&str, alloc::string::String>>::from_external_error
Line
Count
Source
86
757
  fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
87
757
    Error { input, code: kind }
88
757
  }
<nom::error::Error<&str> as nom::error::FromExternalError<&str, core::num::error::ParseIntError>>::from_external_error
Line
Count
Source
86
2.66k
  fn from_external_error(input: I, kind: ErrorKind, _e: E) -> Self {
87
2.66k
    Error { input, code: kind }
88
2.66k
  }
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.14k
  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.14k
  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.97M
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
5.97M
  E::from_error_kind(input, kind)
136
5.97M
}
nom::error::make_error::<(&[u8], usize), nom::error::Error<(&[u8], usize)>>
Line
Count
Source
134
1.50M
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
1.50M
  E::from_error_kind(input, kind)
136
1.50M
}
nom::error::make_error::<&[u8], suricata::quic::error::QuicError>
Line
Count
Source
134
1.11M
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
1.11M
  E::from_error_kind(input, kind)
136
1.11M
}
nom::error::make_error::<&[u8], nom::error::Error<&[u8]>>
Line
Count
Source
134
154k
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
154k
  E::from_error_kind(input, kind)
136
154k
}
nom::error::make_error::<&[u8], nom::error::Error<&[u8]>>
Line
Count
Source
134
23
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
23
  E::from_error_kind(input, kind)
136
23
}
nom::error::make_error::<&[u8], nom::error::Error<&[u8]>>
Line
Count
Source
134
15.6k
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
15.6k
  E::from_error_kind(input, kind)
136
15.6k
}
nom::error::make_error::<&[u8], nom::error::Error<&[u8]>>
Line
Count
Source
134
4.33k
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
4.33k
  E::from_error_kind(input, kind)
136
4.33k
}
Unexecuted instantiation: nom::error::make_error::<_, _>
nom::error::make_error::<(&[u8], usize), nom::error::Error<(&[u8], usize)>>
Line
Count
Source
134
462k
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
462k
  E::from_error_kind(input, kind)
136
462k
}
nom::error::make_error::<&str, nom::error::Error<&str>>
Line
Count
Source
134
1.40k
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
1.40k
  E::from_error_kind(input, kind)
136
1.40k
}
nom::error::make_error::<&[u8], suricata::quic::error::QuicError>
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], nom::error::Error<&[u8]>>
Line
Count
Source
134
268k
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
268k
  E::from_error_kind(input, kind)
136
268k
}
nom::error::make_error::<&[u8], suricata::rdp::error::RdpError>
Line
Count
Source
134
1.10M
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
1.10M
  E::from_error_kind(input, kind)
136
1.10M
}
nom::error::make_error::<&[u8], nom::error::Error<&[u8]>>
Line
Count
Source
134
27
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
27
  E::from_error_kind(input, kind)
136
27
}
nom::error::make_error::<&[u8], nom::error::Error<&[u8]>>
Line
Count
Source
134
25.9k
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
25.9k
  E::from_error_kind(input, kind)
136
25.9k
}
nom::error::make_error::<&[u8], nom::error::Error<&[u8]>>
Line
Count
Source
134
5.23k
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
5.23k
  E::from_error_kind(input, kind)
136
5.23k
}
nom::error::make_error::<&[u8], der_parser::error::BerError>
Line
Count
Source
134
706
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
706
  E::from_error_kind(input, kind)
136
706
}
nom::error::make_error::<&[u8], nom::error::Error<&[u8]>>
Line
Count
Source
134
756
pub fn make_error<I, E: ParseError<I>>(input: I, kind: ErrorKind) -> E {
135
756
  E::from_error_kind(input, kind)
136
756
}
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
*/