1use std::{
2 fmt::{Debug, Display},
3 io::{self},
4 string::FromUtf8Error,
5};
6use thiserror::Error;
7
8type FallbackError = Box<dyn std::error::Error + Send + Sync>;
9
10#[derive(Debug, Error)]
11pub enum Error {
12 #[error("parse failed: {0}")]
13 ParseFailed(FallbackError),
14
15 #[error("io error: {0}")]
16 IOError(std::io::Error),
17
18 #[error("unrecognized file format")]
20 UnrecognizedFileFormat,
21}
22
23#[derive(Debug, Error)]
24pub(crate) enum ParsedError {
25 #[error("no enough bytes")]
26 NoEnoughBytes,
27
28 #[error("io error: {0}")]
29 IOError(std::io::Error),
30
31 #[error("{0}")]
32 Failed(String),
33}
34
35#[derive(Debug, Error)]
73pub(crate) enum ParsingError {
74 #[error("need more bytes: {0}")]
75 Need(usize),
76
77 #[error("clear and skip bytes: {0:?}")]
78 ClearAndSkip(usize),
79
80 #[error("{0}")]
81 Failed(String),
82}
83
84#[derive(Debug, Error)]
85pub(crate) struct ParsingErrorState {
86 pub err: ParsingError,
87 pub state: Option<ParsingState>,
88}
89
90impl ParsingErrorState {
91 pub fn new(err: ParsingError, state: Option<ParsingState>) -> Self {
92 Self { err, state }
93 }
94}
95
96impl Display for ParsingErrorState {
97 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98 Display::fmt(
99 &format!(
100 "ParsingError(err: {}, state: {})",
101 self.err,
102 self.state
103 .as_ref()
104 .map(|x| x.to_string())
105 .unwrap_or("None".to_string())
106 ),
107 f,
108 )
109 }
110}
111
112impl From<&str> for ParsingError {
113 fn from(value: &str) -> Self {
114 Self::Failed(value.to_string())
115 }
116}
117
118impl From<std::io::Error> for ParsedError {
119 fn from(value: std::io::Error) -> Self {
120 Self::IOError(value)
121 }
122}
123
124impl From<ParsedError> for crate::Error {
125 fn from(value: ParsedError) -> Self {
126 match value {
127 ParsedError::NoEnoughBytes => Self::ParseFailed(value.into()),
128 ParsedError::IOError(e) => Self::IOError(e),
129 ParsedError::Failed(e) => Self::ParseFailed(e.into()),
130 }
131 }
132}
133
134use Error::*;
135
136use crate::parser::ParsingState;
137
138impl From<io::Error> for Error {
139 fn from(value: io::Error) -> Self {
140 ParseFailed(value.into())
141 }
142}
143
144impl From<String> for Error {
145 fn from(src: String) -> Error {
146 ParseFailed(src.into())
147 }
148}
149
150impl From<&str> for Error {
151 fn from(src: &str) -> Error {
152 src.to_string().into()
153 }
154}
155
156impl From<FromUtf8Error> for Error {
157 fn from(value: FromUtf8Error) -> Self {
158 ParseFailed(value.into())
159 }
160}
161
162impl<T: Debug> From<nom::Err<nom::error::Error<T>>> for crate::Error {
163 fn from(e: nom::Err<nom::error::Error<T>>) -> Self {
164 convert_parse_error(e, "")
165 }
166}
167
168pub(crate) fn convert_parse_error<T: Debug>(
169 e: nom::Err<nom::error::Error<T>>,
170 message: &str,
171) -> Error {
172 let s = match e {
173 nom::Err::Incomplete(_) => format!("{e}; {message}"),
174 nom::Err::Error(e) => format!("{}; {message}", e.code.description()),
175 nom::Err::Failure(e) => format!("{}; {message}", e.code.description()),
176 };
177
178 s.into()
179}
180
181impl From<nom::Err<nom::error::Error<&[u8]>>> for ParsingError {
182 fn from(e: nom::Err<nom::error::Error<&[u8]>>) -> Self {
183 match e {
184 nom::Err::Incomplete(needed) => match needed {
185 nom::Needed::Unknown => ParsingError::Need(1),
186 nom::Needed::Size(n) => ParsingError::Need(n.get()),
187 },
188 nom::Err::Failure(e) | nom::Err::Error(e) => {
189 ParsingError::Failed(e.code.description().to_string())
190 }
191 }
192 }
193}
194
195pub(crate) fn nom_error_to_parsing_error_with_state(
210 e: nom::Err<nom::error::Error<&[u8]>>,
211 state: Option<ParsingState>,
212) -> ParsingErrorState {
213 match e {
214 nom::Err::Incomplete(needed) => match needed {
215 nom::Needed::Unknown => ParsingErrorState::new(ParsingError::Need(1), state),
216 nom::Needed::Size(n) => ParsingErrorState::new(ParsingError::Need(n.get()), state),
217 },
218 nom::Err::Failure(e) | nom::Err::Error(e) => ParsingErrorState::new(
219 ParsingError::Failed(e.code.description().to_string()),
220 state,
221 ),
222 }
223}