1use super::*;
2
3const ERROR: &str = "error";
4const OS: &str = "os";
5const SOURCE: &str = "source";
6const BACKTRACE: &str = "backtrace";
7const MESSAGE: &str = "message";
8
9pub struct OneErr(std::io::Error);
11
12impl std::fmt::Display for OneErr {
13 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14 fmt_display(f, self)
15 }
16}
17
18impl std::fmt::Debug for OneErr {
19 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20 if f.alternate() {
21 fmt_debug_alt(f, self)
22 } else {
23 fmt_display(f, self)
24 }
25 }
26}
27
28impl std::error::Error for OneErr {}
29
30impl Clone for OneErr {
31 fn clone(&self) -> Self {
32 let k = self.0.kind();
33 Self(std::io::Error::new(k, self.priv_as_inner().clone()))
34 }
35}
36
37impl PartialEq for OneErr {
38 fn eq(&self, oth: &Self) -> bool {
39 if self.str_kind() != oth.str_kind() {
40 return false;
41 }
42 self.priv_as_inner() == oth.priv_as_inner()
43 }
44}
45
46impl Eq for OneErr {}
47
48impl From<std::io::ErrorKind> for OneErr {
49 fn from(k: std::io::ErrorKind) -> Self {
50 Self(std::io::Error::new(k, OneErrInner::new()))
51 }
52}
53
54impl From<i32> for OneErr {
55 fn from(e: i32) -> Self {
56 ErrNo::from(e).into()
57 }
58}
59
60impl From<ErrNo> for OneErr {
61 fn from(e: ErrNo) -> Self {
62 let k: std::io::ErrorKind = (&e).into();
63
64 let mut inner = OneErrInner::new();
65 if let std::io::ErrorKind::Other = k {
66 if let ErrNo::Other = e {
67 } else {
69 inner.set_field(OS.into(), i32::from(&e) as i64);
70 }
71 }
72
73 Self(std::io::Error::new(k, inner))
74 }
75}
76
77impl From<std::io::Error> for OneErr {
78 fn from(e: std::io::Error) -> Self {
79 if let Some(r) = e.get_ref() {
85 if r.downcast_ref::<OneErrInner>().is_some() {
86 return Self(e);
87 }
88 }
89
90 if let Some(e) = e.raw_os_error() {
92 return e.into();
93 }
94
95 let message = format!("{}", e);
97 let mut inner = OneErrInner::new();
98 inner.set_field(MESSAGE.into(), message);
99 Self(std::io::Error::new(e.kind(), inner))
100 }
101}
102
103impl From<()> for OneErr {
104 fn from(_: ()) -> Self {
105 std::io::ErrorKind::Other.into()
106 }
107}
108
109impl From<String> for OneErr {
110 fn from(s: String) -> Self {
111 s.as_str().into()
112 }
113}
114
115impl From<&String> for OneErr {
116 fn from(s: &String) -> Self {
117 s.as_str().into()
118 }
119}
120
121impl From<&str> for OneErr {
122 fn from(s: &str) -> Self {
123 OneErr::new(s)
124 }
125}
126
127impl From<OneErr> for std::io::Error {
128 fn from(e: OneErr) -> Self {
129 e.0
130 }
131}
132
133impl From<&OneErr> for std::io::Error {
134 fn from(e: &OneErr) -> Self {
135 e.clone().0
136 }
137}
138
139impl std::ops::Deref for OneErr {
140 type Target = std::io::Error;
141
142 fn deref(&self) -> &Self::Target {
143 &self.0
144 }
145}
146
147impl AsRef<std::io::Error> for OneErr {
148 fn as_ref(&self) -> &std::io::Error {
149 &self.0
150 }
151}
152
153impl serde::Serialize for OneErr {
154 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
155 where
156 S: serde::Serializer,
157 {
158 use serde::ser::SerializeMap;
159
160 let (kind, os, inner) = self.priv_as_parts();
161 let error: &str = if let Some(os) = os {
162 if let ErrNo::Other = os {
163 if let Some(f) = &*inner.0 {
164 if let Some(e_str) = f.get(ERROR) {
165 if let Some(e_str) = e_str.as_str() {
166 e_str
167 } else {
168 <&'static str>::from(os)
169 }
170 } else {
171 <&'static str>::from(os)
172 }
173 } else {
174 <&'static str>::from(os)
175 }
176 } else {
177 <&'static str>::from(os)
178 }
179 } else {
180 if let std::io::ErrorKind::Other = kind {
181 if let Some(f) = &*inner.0 {
182 if let Some(e_str) = f.get(ERROR) {
183 if let Some(e_str) = e_str.as_str() {
184 e_str
185 } else {
186 err_kind_to_str(kind)
187 }
188 } else {
189 err_kind_to_str(kind)
190 }
191 } else {
192 err_kind_to_str(kind)
193 }
194 } else {
195 err_kind_to_str(kind)
196 }
197 };
198
199 let mut count = 1;
200 if let Some(f) = &*inner.0 {
201 count += f.len();
202
203 if f.contains_key(ERROR) {
204 count -= 1;
205 }
206
207 if f.contains_key(OS) {
208 count -= 1;
209 }
210 }
211
212 let mut map = serializer.serialize_map(Some(count))?;
213
214 map.serialize_entry(ERROR, &error)?;
215
216 if let Some(f) = &*inner.0 {
217 for (n, v) in f.iter() {
218 match &**n {
219 ERROR | OS => continue,
220 _ => map.serialize_entry(n, v)?,
221 }
222 }
223 }
224
225 map.end()
226 }
227}
228
229impl<'de> serde::Deserialize<'de> for OneErr {
230 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
231 where
232 D: serde::Deserializer<'de>,
233 {
234 struct V;
235 impl<'de> serde::de::Visitor<'de> for V {
236 type Value = TopMap;
237
238 fn expecting(
239 &self,
240 f: &mut std::fmt::Formatter<'_>,
241 ) -> std::fmt::Result {
242 f.write_str("OneErr Map")
243 }
244
245 fn visit_map<A>(
246 self,
247 mut access: A,
248 ) -> Result<Self::Value, A::Error>
249 where
250 A: serde::de::MapAccess<'de>,
251 {
252 let mut out_map = TopMap::new();
253 loop {
254 let r: Option<(Box<str>, Value)> = access.next_entry()?;
255 match r {
256 None => break,
257 Some((k, v)) => {
258 out_map.insert(k, v);
259 }
260 }
261 }
262 Ok(out_map)
263 }
264 }
265 let mut top_map: TopMap = deserializer.deserialize_map(V)?;
266 if let Some(error) = top_map.remove(ERROR) {
267 if let Some(error) = error.as_str() {
268 let (kind, os) = parse_err_str(error);
269 if let Some(os) = os {
270 if let std::io::ErrorKind::Other = kind {
271 top_map
272 .insert(OS.into(), (i32::from(&os) as i64).into());
273 }
274 } else {
275 if let std::io::ErrorKind::Other = kind {
276 if error != "Other" && error != "EOTHER" {
277 top_map.insert(ERROR.into(), error.into());
278 }
279 }
280 }
281 if top_map.is_empty() {
282 Ok(Self(std::io::Error::new(kind, OneErrInner::new())))
283 } else {
284 Ok(Self(std::io::Error::new(
285 kind,
286 OneErrInner(Box::new(Some(top_map))),
287 )))
288 }
289 } else {
290 Err(serde::de::Error::custom("required 'error' field is a str"))
291 }
292 } else {
293 Err(serde::de::Error::custom("required 'error' field"))
294 }
295 }
296}
297
298impl std::str::FromStr for OneErr {
299 type Err = OneErr;
300
301 fn from_str(s: &str) -> Result<Self, Self::Err> {
302 serde_json::from_str(s).map_err(|e| {
303 OneErr::with_message(crate::io_error::INVALID_DATA_STR, &e)
304 })
305 }
306}
307
308impl OneErr {
309 pub fn new<K>(kind: K) -> Self
311 where
312 K: std::fmt::Display,
313 {
314 let kind_str = kind.to_string();
315 let (kind, os) = parse_err_str(&kind_str);
316 if let Some(os) = os {
317 if let ErrNo::Other = os {
318 let mut inner = OneErrInner::new();
319 inner.set_field(ERROR.into(), kind_str);
320
321 Self(std::io::Error::new(kind, inner))
322 } else {
323 os.into()
324 }
325 } else {
326 if let std::io::ErrorKind::Other = kind {
327 let mut inner = OneErrInner::new();
328 inner.set_field(ERROR.into(), kind_str);
329
330 Self(std::io::Error::new(kind, inner))
331 } else {
332 kind.into()
333 }
334 }
335 }
336
337 pub fn with_message<K, M>(kind: K, message: M) -> Self
339 where
340 K: std::fmt::Display,
341 M: std::fmt::Display,
342 {
343 let mut err = Self::new(kind);
344 err.priv_as_inner_mut()
345 .set_field(MESSAGE.into(), message.to_string());
346 err
347 }
348
349 pub fn io_kind(&self) -> std::io::ErrorKind {
351 self.0.kind()
352 }
353
354 pub fn errno(&self) -> ErrNo {
356 let inner = self.priv_as_inner();
357
358 if let Some(os) = inner.get_field::<i64>(OS) {
359 return ErrNo::from(os as i32);
360 }
361
362 ErrNo::from(self.0.kind())
363 }
364
365 pub fn str_kind(&self) -> &str {
369 let inner = self.priv_as_inner();
370
371 if let Some(e_str) = inner.get_field::<&str>(ERROR) {
372 return e_str;
373 }
374
375 if let Some(os) = inner.get_field::<i64>(OS) {
376 let os = ErrNo::from(os as i32);
377 return <&'static str>::from(os);
378 }
379
380 err_kind_to_str(self.0.kind())
381 }
382
383 pub fn as_io(&self) -> &std::io::Error {
385 self.as_ref()
386 }
387
388 pub fn set_field<K, T>(&mut self, name: &K, t: T) -> &mut Self
392 where
393 K: ?Sized + std::fmt::Display,
394 T: Into<Value>,
395 {
396 let name = name.to_string().into_boxed_str();
397 match &*name {
398 ERROR | OS | SOURCE | BACKTRACE | MESSAGE => {
399 panic!("field name '{}' is reserved", name)
400 }
401 _ => (),
402 }
403
404 self.priv_as_inner_mut().set_field(name, t);
405 self
406 }
407
408 pub fn get_message(&self) -> Option<&str> {
410 self.get_field(MESSAGE)
411 }
412
413 pub fn get_field<'lt, R, V>(&'lt self, name: R) -> Option<V>
417 where
418 R: AsRef<str>,
419 Option<V>: From<&'lt Value>,
420 {
421 self.priv_as_inner().get_field(name.as_ref())
422 }
423}
424
425impl OneErr {
428 pub(crate) fn priv_as_inner(&self) -> &OneErrInner {
429 self.0
432 .get_ref()
433 .unwrap()
434 .downcast_ref::<OneErrInner>()
435 .unwrap()
436 }
437
438 pub(crate) fn priv_as_parts(
439 &self,
440 ) -> (std::io::ErrorKind, Option<ErrNo>, &OneErrInner) {
441 let kind = self.0.kind();
442 let inner = self.priv_as_inner();
443 let os = inner.get_field::<i64>(OS).map(|e| ErrNo::from(e as i32));
444 (kind, os, inner)
445 }
446
447 pub(crate) fn priv_as_inner_mut(&mut self) -> &mut OneErrInner {
448 self.0
451 .get_mut()
452 .unwrap()
453 .downcast_mut::<OneErrInner>()
454 .unwrap()
455 }
456}