1use std::convert::Infallible;
2use std::error::Error as StdError;
3use std::fmt::Result as FmtResult;
4use std::fmt::{Display, Formatter};
5use std::result::Result as StdResult;
6
7pub const WRONG_OFFSET: &str = "Wrong buffer offset detected";
9
10#[derive(Debug)]
12#[non_exhaustive]
13pub enum Error {
14 Invalid {
16 desc: String,
17 source: Option<Box<dyn StdError + Send + Sync + 'static>>,
18 },
19
20 Read {
23 desc: String,
24 source: Option<Box<dyn StdError + Send + Sync + 'static>>,
25 },
26
27 Write {
30 desc: String,
31 source: Option<Box<dyn StdError + Send + Sync + 'static>>,
32 },
33
34 NotImplemented { desc: String },
37
38 Internal {
42 desc: String,
43 source: Option<Box<dyn StdError + Send + Sync + 'static>>,
44 },
45}
46
47impl Error {
48 pub fn invalid<T, C>(desc: C) -> Result<T>
50 where
51 C: Display + Send + Sync + 'static,
52 {
53 Err(Error::Invalid {
54 desc: desc.to_string(),
55 source: None,
56 })
57 }
58
59 pub fn not_implemented<T, C>(desc: C) -> Result<T>
61 where
62 C: Display + Send + Sync + 'static,
63 {
64 Err(Error::NotImplemented {
65 desc: desc.to_string(),
66 })
67 }
68
69 pub fn internal<T, C>(desc: C) -> Result<T>
71 where
72 C: Display + Send + Sync + 'static,
73 {
74 Err(Error::Internal {
75 desc: desc.to_string(),
76 source: None,
77 })
78 }
79}
80
81impl Display for Error {
82 fn fmt(&self, f: &mut Formatter) -> FmtResult {
83 match self {
84 Error::Invalid { desc, .. } => write!(f, "Invalid E57 content: {desc}"),
85 Error::Read { desc, .. } => write!(f, "Failed to read E57: {desc}"),
86 Error::Internal { desc, .. } => write!(f, "Internal error: {desc}"),
87 Error::NotImplemented { desc } => write!(f, "Not implemented: {desc}"),
88 Error::Write { desc, .. } => write!(f, "Failed to write E57: {desc}"),
89 }
90 }
91}
92
93impl StdError for Error {
94 fn source(&self) -> Option<&(dyn StdError + 'static)> {
95 match self {
96 Error::Invalid { source, .. } => source
97 .as_ref()
98 .map(|s| s.as_ref() as &(dyn StdError + 'static)),
99 Error::Read { source, .. } => source
100 .as_ref()
101 .map(|s| s.as_ref() as &(dyn StdError + 'static)),
102 Error::Internal { source, .. } => source
103 .as_ref()
104 .map(|s| s.as_ref() as &(dyn StdError + 'static)),
105 Error::Write { source, .. } => source
106 .as_ref()
107 .map(|s| s.as_ref() as &(dyn StdError + 'static)),
108 Error::NotImplemented { .. } => None,
109 }
110 }
111}
112
113pub type Result<T> = StdResult<T, Error>;
115
116pub trait Converter<T, E> {
118 fn read_err<C>(self, context: C) -> Result<T>
119 where
120 C: Display + Send + Sync + 'static;
121
122 fn invalid_err<C>(self, context: C) -> Result<T>
123 where
124 C: Display + Send + Sync + 'static;
125
126 fn internal_err<C>(self, context: C) -> Result<T>
127 where
128 C: Display + Send + Sync + 'static;
129
130 fn write_err<C>(self, context: C) -> Result<T>
131 where
132 C: Display + Send + Sync + 'static;
133}
134
135impl<T, E> Converter<T, E> for StdResult<T, E>
137where
138 E: StdError + Send + Sync + 'static,
139{
140 fn read_err<C>(self, desc: C) -> Result<T>
141 where
142 C: Display + Send + Sync + 'static,
143 {
144 match self {
145 Ok(ok) => Ok(ok),
146 Err(error) => Err(Error::Read {
147 desc: desc.to_string(),
148 source: Some(Box::new(error)),
149 }),
150 }
151 }
152
153 fn invalid_err<C>(self, desc: C) -> Result<T>
154 where
155 C: Display + Send + Sync + 'static,
156 {
157 match self {
158 Ok(ok) => Ok(ok),
159 Err(error) => Err(Error::Invalid {
160 desc: desc.to_string(),
161 source: Some(Box::new(error)),
162 }),
163 }
164 }
165
166 fn internal_err<C>(self, desc: C) -> Result<T>
167 where
168 C: Display + Send + Sync + 'static,
169 {
170 match self {
171 Ok(ok) => Ok(ok),
172 Err(error) => Err(Error::Internal {
173 desc: desc.to_string(),
174 source: Some(Box::new(error)),
175 }),
176 }
177 }
178
179 fn write_err<C>(self, desc: C) -> Result<T>
180 where
181 C: Display + Send + Sync + 'static,
182 {
183 match self {
184 Ok(ok) => Ok(ok),
185 Err(error) => Err(Error::Write {
186 desc: desc.to_string(),
187 source: Some(Box::new(error)),
188 }),
189 }
190 }
191}
192
193impl<T> Converter<T, Infallible> for Option<T> {
195 fn read_err<C>(self, desc: C) -> Result<T>
196 where
197 C: Display + Send + Sync + 'static,
198 {
199 match self {
200 Some(ok) => Ok(ok),
201 None => Err(Error::Read {
202 desc: desc.to_string(),
203 source: None,
204 }),
205 }
206 }
207
208 fn invalid_err<C>(self, desc: C) -> Result<T>
209 where
210 C: Display + Send + Sync + 'static,
211 {
212 match self {
213 Some(ok) => Ok(ok),
214 None => Err(Error::Invalid {
215 desc: desc.to_string(),
216 source: None,
217 }),
218 }
219 }
220
221 fn internal_err<C>(self, desc: C) -> Result<T>
222 where
223 C: Display + Send + Sync + 'static,
224 {
225 match self {
226 Some(ok) => Ok(ok),
227 None => Err(Error::Internal {
228 desc: desc.to_string(),
229 source: None,
230 }),
231 }
232 }
233
234 fn write_err<C>(self, desc: C) -> Result<T>
235 where
236 C: Display + Send + Sync + 'static,
237 {
238 match self {
239 Some(ok) => Ok(ok),
240 None => Err(Error::Write {
241 desc: desc.to_string(),
242 source: None,
243 }),
244 }
245 }
246}