1 | use crate::utils::Context; |
2 | |
3 | use std::{error::Error as StdError, fmt, io}; |
4 | |
5 | /// Wrap `std::io::Error` with additional message |
6 | /// |
7 | /// Keeps the original error kind and stores the original I/O error as `source`. |
8 | impl<T> Context for Result<T, std::io::Error> { |
9 | fn context(self, message: impl Fn() -> String) -> Self { |
10 | self.map_err(|e: Error| VerboseError::wrap(source:e, message())) |
11 | } |
12 | } |
13 | |
14 | #[derive (Debug)] |
15 | pub(crate) struct VerboseError { |
16 | source: io::Error, |
17 | message: String, |
18 | } |
19 | |
20 | impl VerboseError { |
21 | pub(crate) fn wrap(source: io::Error, message: impl Into<String>) -> io::Error { |
22 | io::Error::new( |
23 | source.kind(), |
24 | error:VerboseError { |
25 | source, |
26 | message: message.into(), |
27 | }, |
28 | ) |
29 | } |
30 | } |
31 | |
32 | impl fmt::Display for VerboseError { |
33 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
34 | write!(f, " {}" , self.message) |
35 | } |
36 | } |
37 | |
38 | impl StdError for VerboseError { |
39 | fn source(&self) -> Option<&(dyn StdError + 'static)> { |
40 | Some(&self.source) |
41 | } |
42 | } |
43 | |