use std::error; use std::fmt; /// An error that can occur in this crate. /// /// Generally, this error corresponds to problems with underlying process. #[derive(Debug)] pub struct Error { source: Vec, kind: ErrorKind, } #[derive(Debug)] #[non_exhaustive] pub enum ErrorKind { Config, Fetch, // TODO: merge into "Update" or "Command" type of error? => Have this as an other level of error? Compile, // TODO: merge into "Update" or "Command" type of error? => Have this as an other level of error? Install, // TODO: merge into "Update" or "Command" type of error? => Have this as an other level of error? } impl Error { pub(crate) fn new(source: Vec, kind: ErrorKind) -> Error { Error { source, kind } } /// Return the kind of this error. pub fn kind(&self) -> &ErrorKind { &self.kind } } impl error::Error for Error { fn source(&self) -> Option<&(dyn error::Error + 'static)> { if self.source.is_empty() { None } else { Some(&self.source[0]) } } } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use std::error::Error; match self.kind { ErrorKind::Config => write!( f, "Could not read configuration file: {}", self.source().unwrap() ), ErrorKind::Fetch => write!(f, "Could not install: {}", self.source().unwrap()), ErrorKind::Compile => write!(f, "Could not install: {}", self.source().unwrap()), ErrorKind::Install => write!(f, "Could not install: {}", self.source().unwrap()), } } }