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