use crate::utils::Context; use std::{error::Error as StdError, fmt, io}; /// Wrap `std::io::Error` with additional message /// /// Keeps the original error kind and stores the original I/O error as `source`. impl Context for Result { fn context(self, message: impl Fn() -> String) -> Self { self.map_err(|e| VerboseError::wrap(e, message())) } } #[derive(Debug)] pub(crate) struct VerboseError { source: io::Error, message: String, } impl VerboseError { pub(crate) fn wrap(source: io::Error, message: impl Into) -> io::Error { io::Error::new( source.kind(), VerboseError { source, message: message.into(), }, ) } } impl fmt::Display for VerboseError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.message) } } impl StdError for VerboseError { fn source(&self) -> Option<&(dyn StdError + 'static)> { Some(&self.source) } }