use std::{error, fmt, io, result};
pub type Result<T> = result::Result<T, Error>;
#[derive(Debug)]
pub struct Error {
message: String,
source: ErrorSource,
}
#[derive(Debug)]
pub enum ErrorSource {
Io(io::Error),
None,
}
impl Error {
pub(crate) fn new<T: fmt::Display>(msg: T) -> Self {
Self {
message: msg.to_string(),
source: ErrorSource::None,
}
}
pub(crate) fn io_error<T: fmt::Display>(msg: T, source: io::Error) -> Self {
Self {
message: msg.to_string(),
source: ErrorSource::Io(source),
}
}
}
impl Error {
pub fn error_source(&self) -> &ErrorSource {
&self.source
}
pub fn raw_os_error(&self) -> Option<i32> {
match &self.source {
ErrorSource::Io(source) => source.raw_os_error(),
_ => None,
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.message)?;
match &self.source {
ErrorSource::Io(source) => {
f.write_fmt(format_args!(": {}", source))?;
}
ErrorSource::None => (),
}
Ok(())
}
}
impl error::Error for Error {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match &self.source {
ErrorSource::Io(source) => Some(source),
ErrorSource::None => None,
}
}
}