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 { fn with_err_path(self, path: F) -> Self where F: FnOnce() -> P, P: Into; } impl IoResultExt for Result { fn with_err_path(self, path: F) -> Self where F: FnOnce() -> P, P: Into, { self.map_err(|e| { io::Error::new( e.kind(), PathError { path: path().into(), err: e, }, ) }) } }