1 | use std::path::PathBuf; |
2 | use std::{error, fmt, io}; |
3 | |
4 | #[derive(Debug)] |
5 | struct PathError { |
6 | path: PathBuf, |
7 | err: io::Error, |
8 | } |
9 | |
10 | impl fmt::Display for PathError { |
11 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
12 | write!(f, "{} at path {:?}" , self.err, self.path) |
13 | } |
14 | } |
15 | |
16 | impl error::Error for PathError { |
17 | fn source(&self) -> Option<&(dyn error::Error + 'static)> { |
18 | self.err.source() |
19 | } |
20 | } |
21 | |
22 | pub(crate) trait IoResultExt<T> { |
23 | fn with_err_path<F, P>(self, path: F) -> Self |
24 | where |
25 | F: FnOnce() -> P, |
26 | P: Into<PathBuf>; |
27 | } |
28 | |
29 | impl<T> IoResultExt<T> for Result<T, io::Error> { |
30 | fn with_err_path<F, P>(self, path: F) -> Self |
31 | where |
32 | F: FnOnce() -> P, |
33 | P: Into<PathBuf>, |
34 | { |
35 | self.map_err(|e| { |
36 | io::Error::new( |
37 | e.kind(), |
38 | PathError { |
39 | path: path().into(), |
40 | err: e, |
41 | }, |
42 | ) |
43 | }) |
44 | } |
45 | } |
46 | |