libjess/
errors.rs

1//! Custom error types
2
3use std::fmt;
4
5use std::io;
6use std::path;
7
8/// Type alias for result<T, [`Error`]>
9pub type Result<T> = std::result::Result<T, WrappedError>;
10
11/// Custom I/O Error which adds context information to the original
12#[derive(Debug, Default)]
13pub struct WrappedError {
14    pub(crate) inner: Repr,
15}
16
17/// Inner representation of the custom error
18#[derive(Debug)]
19pub(crate) enum Repr {
20    IO {
21        base: io::Error,
22        file: path::PathBuf,
23    },
24    Simple(Kind),
25}
26
27/// Error options
28#[derive(Debug)]
29pub enum Kind {
30    /// Used when no variants apply
31    Unknown,
32}
33
34impl Default for Repr {
35    fn default() -> Self {
36        Repr::Simple(Kind::Unknown)
37    }
38}
39
40impl WrappedError {
41    ///Consume the error, returning the internal error if any
42    pub fn into_inner(self) -> Option<Box<dyn std::error::Error>> {
43        match self.inner {
44            Repr::IO { base, .. } => Some(Box::new(base)),
45            Repr::Simple(_) => None,
46        }
47    }
48
49    /// Get the inner io::error if any
50    pub fn get_io_error(&self) -> Option<&io::Error> {
51        match &self.inner {
52            Repr::IO { base, .. } => Some(base),
53            _ => None,
54        }
55    }
56
57    /// Create a new error from the original error and the path that provoced the error
58    pub fn from(kind: Kind) -> Self {
59        Self {
60            inner: Repr::Simple(kind),
61        }
62    }
63
64    /// Create IO error
65    pub fn io_error(base: io::Error, file: impl AsRef<path::Path>) -> Self {
66        Self {
67            inner: Repr::IO {
68                file: file.as_ref().to_owned(),
69                base,
70            },
71        }
72    }
73}
74
75impl fmt::Display for Kind {
76    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
77        match &self {
78            Kind::Unknown => write!(f, "Unknown error"),
79        }
80    }
81}
82
83impl fmt::Display for WrappedError {
84    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85        match &self.inner {
86            #[cfg(feature = "fs")]
87            Repr::IO { base, file } => {
88                write!(f, "{}, file: {:?}", base.to_string(), file.as_os_str())
89            }
90            Repr::Simple(kind) => write!(f, "{}", kind.to_string()),
91        }
92    }
93}
94
95impl std::error::Error for WrappedError {}