Skip to main content

libtpfanspeed/
error.rs

1#[derive(Debug, Clone)]
2pub struct Error {
3    kind: ErrorKind,
4    description: Option<String>,
5    help: Option<String>,
6}
7
8#[derive(Debug, Clone)]
9pub enum ErrorKind {
10    PermissionDenied,
11    FanControlDisabled,
12    InvalidValue,
13    FileNotFound,
14    ValueTooHigh,
15    ValueTooLow,
16    GenericError,
17}
18
19/// Quickly construct an err::Error.
20///
21/// Note: the kind arguments only require you to supply the enum variant. Assume
22/// that err::ErrorKind::* is already included.
23///
24/// Function signatures include:
25///  * `kind: err::ErrorKind`
26///  * `kind: err::ErrorKind, description: impl ToString`
27///  * `kind: err::ErrorKind, help: impl ToString, description: impl ToString`
28///  * `kind: err::ErrorKind, help: impl ToString, format: &str, format args`
29///  * `kind: err::ErrorKind, format: &str, format args`
30///
31///
32#[macro_export]
33macro_rules! err {
34    ($kind:expr) => {
35        $crate::error::Error::without_description_help($kind)
36    };
37    ($kind:ident,$description:expr) => {
38        $crate::error::Error::without_help($crate::error::ErrorKind::$kind, $description.to_string())
39    };
40    ($kind:ident,$help: expr, $description: expr) => {
41        $crate::error::Error::new($crate::error::ErrorKind::$kind, $description.to_string(), $help.to_string())
42    };
43    ($kind:ident,$help:expr, $format:expr, $($fmt_arg:tt)*) => {
44        $crate::error::Error::new($crate::error::ErrorKind::$kind, format!($format, $($fmt_arg)*), $help.to_string())
45    };
46    ($kind:ident,$format:expr,$($fmt_arg:tt)*) => {
47        $crate::error::Error::without_help($crate::error::ErrorKind::$kind, format!($format, $($fmt_arg)*))
48    };
49}
50
51#[macro_export]
52/// Quickly construct a Generic Error.
53macro_rules! generic_err {
54    ($err:expr) => {
55        $crate::err!(GenericError, "Some error occurred: {}", $err)
56    };
57}
58
59pub use crate::{err, generic_err};
60
61impl std::fmt::Display for ErrorKind {
62    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63        use ErrorKind as E;
64        let s = match self {
65            E::ValueTooLow => "Fan speed setting too low",
66            E::ValueTooHigh => "Fan speed setting too high",
67            E::InvalidValue => "Fan speed setting invalid",
68            E::FileNotFound => "File not found",
69            E::PermissionDenied => "Permission Denied",
70            E::FanControlDisabled => "Fan control disabled",
71            E::GenericError => "Generic error",
72        };
73
74        write!(f, "{s}")
75    }
76}
77
78impl Error {
79    pub fn new(kind: ErrorKind, description: String, help: String) -> Self {
80        Self {
81            kind,
82            description: Some(description),
83            help: Some(help),
84        }
85    }
86
87    pub fn without_description_help(kind: ErrorKind) -> Self {
88        Self {
89            kind,
90            description: None,
91            help: None,
92        }
93    }
94
95    pub fn without_description(kind: ErrorKind, help: String) -> Self {
96        Self {
97            kind,
98            description: None,
99            help: Some(help),
100        }
101    }
102
103    pub fn without_help(kind: ErrorKind, description: String) -> Self {
104        Self {
105            kind,
106            description: Some(description),
107            help: None,
108        }
109    }
110
111    pub fn kind(&self) -> &ErrorKind {
112        &self.kind
113    }
114
115    pub fn desc(&self) -> Option<&str> {
116        if let Some(ref desc) = self.description {
117            Some(desc.as_str())
118        } else {
119            None
120        }
121    }
122
123    pub fn help(&self) -> Option<&str> {
124        if let Some(ref help) = self.help {
125            Some(help.as_str())
126        } else {
127            None
128        }
129    }
130}
131
132impl std::fmt::Display for Error {
133    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
134        write!(f, "{}", self.kind())?;
135        if let Some(ref desc) = self.description {
136            write!(f, ": {}", desc)?;
137        }
138        Ok(())
139    }
140}
141
142impl std::error::Error for Error {
143    fn description(&self) -> &str {
144        match &self.description {
145            Some(s) => s.as_ref(),
146            None => "",
147        }
148    }
149
150    fn cause(&self) -> Option<&dyn std::error::Error> {
151        None
152    }
153
154    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
155        None
156    }
157}