Skip to main content

gengo/
error.rs

1use std::error::Error as ErrorTrait;
2use std::fmt;
3
4macro_rules! error_kind {
5    ($($name:ident, $message:literal),*) => {
6        /// The kind of error that occurred.
7        #[derive(Debug)]
8        #[non_exhaustive]
9        pub enum ErrorKind {
10            $(
11                $name,
12            )*
13        }
14
15        impl fmt::Display for ErrorKind {
16            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17                match self {
18                    $(
19                        Self::$name => write!(f, $message),
20                    )*
21                }
22            }
23        }
24    };
25}
26
27error_kind!(NoRepository, "no repository found");
28
29impl ErrorTrait for ErrorKind {}
30
31#[derive(Debug)]
32pub struct Error {
33    kind: ErrorKind,
34    source: Option<Box<dyn ErrorTrait>>,
35}
36
37impl Error {
38    pub fn new(kind: ErrorKind) -> Self {
39        Self { kind, source: None }
40    }
41
42    pub fn with_source(kind: ErrorKind, source: impl ErrorTrait + 'static) -> Self {
43        Self {
44            kind,
45            source: Some(Box::new(source)),
46        }
47    }
48
49    pub fn kind(&self) -> &ErrorKind {
50        &self.kind
51    }
52}
53
54impl fmt::Display for Error {
55    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56        write!(f, "{}", &self.kind)
57    }
58}
59
60impl ErrorTrait for Error {
61    fn source(&self) -> Option<&(dyn ErrorTrait + 'static)> {
62        self.source.as_ref().map(|s| s.as_ref())
63    }
64}