pace_rs/
error.rs

1//! Error types
2
3use abscissa_core::error::{BoxError, Context};
4use std::{
5    fmt::{self, Display},
6    io,
7    ops::Deref,
8};
9use thiserror::Error;
10
11/// Kinds of errors
12#[derive(Copy, Clone, Debug, Eq, Error, PartialEq)]
13pub enum ErrorKind {
14    /// Error in configuration file
15    #[error("config error")]
16    Config,
17
18    /// Input/output error
19    #[error("I/O error")]
20    Io,
21}
22
23impl ErrorKind {
24    /// Create an error context from this error
25    pub fn context(self, source: impl Into<BoxError>) -> Context<Self> {
26        Context::new(self, Some(source.into()))
27    }
28}
29
30/// Error type
31#[derive(Debug)]
32pub struct Error(Box<Context<ErrorKind>>);
33
34impl Deref for Error {
35    type Target = Context<ErrorKind>;
36
37    fn deref(&self) -> &Context<ErrorKind> {
38        &self.0
39    }
40}
41
42impl Display for Error {
43    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44        self.0.fmt(f)
45    }
46}
47
48impl std::error::Error for Error {
49    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
50        self.0.source()
51    }
52}
53
54impl From<ErrorKind> for Error {
55    fn from(kind: ErrorKind) -> Self {
56        Context::new(kind, None).into()
57    }
58}
59
60impl From<Context<ErrorKind>> for Error {
61    fn from(context: Context<ErrorKind>) -> Self {
62        Self(Box::new(context))
63    }
64}
65
66impl From<io::Error> for Error {
67    fn from(err: io::Error) -> Self {
68        ErrorKind::Io.context(err).into()
69    }
70}