blob: 0ba3ecb2dcb4fa73451df704f3dfabf2e1758172 [file] [log] [blame]
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<T> Context for Result<T, std::io::Error> {
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<String>) -> 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)
}
}