1use abscissa_core::error::{BoxError, Context};
4use std::{
5 fmt::{self, Display},
6 io,
7 ops::Deref,
8};
9use thiserror::Error;
10
11#[derive(Copy, Clone, Debug, Eq, Error, PartialEq)]
13pub enum ErrorKind {
14 #[error("config error")]
16 Config,
17
18 #[error("I/O error")]
20 Io,
21}
22
23impl ErrorKind {
24 pub fn context(self, source: impl Into<BoxError>) -> Context<Self> {
26 Context::new(self, Some(source.into()))
27 }
28}
29
30#[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}