heim_common/
errors.rs

1use std::borrow::Cow;
2use std::error;
3use std::ffi;
4use std::fmt;
5use std::io;
6use std::net;
7use std::num;
8use std::result;
9use std::string;
10
11/// Type alias for types returned by `heim` functions.
12pub type Result<T> = result::Result<T, Error>;
13
14/// Any error which may happen during the data fetch.
15///
16/// Usually means that `heim` is not compatible
17/// with a system it's running on.
18///
19/// Users should consider this enum as opaque type (kinda like with `Box<dyn Error>`)
20/// and use the data in it only for debugging reasons.
21/// Contents of this enum are not stable and may
22/// change without any warning.
23#[derive(Debug)]
24pub enum Error {
25    #[doc(hidden)]
26    MissingEntity(Cow<'static, str>),
27    #[doc(hidden)]
28    Incompatible(Cow<'static, str>),
29    #[doc(hidden)]
30    Io(io::Error),
31    #[doc(hidden)]
32    Other(Box<dyn error::Error + Send + 'static>),
33
34    #[doc(hidden)]
35    __Nonexhaustive,
36}
37
38impl Error {
39    #[doc(hidden)]
40    pub fn last_os_error() -> Error {
41        Error::from(io::Error::last_os_error())
42    }
43
44    #[doc(hidden)]
45    pub fn raw_os_error(&self) -> Option<i32> {
46        match self {
47            Error::Io(e) => e.raw_os_error(),
48            _ => None,
49        }
50    }
51
52    #[doc(hidden)]
53    pub fn missing_entity<T: Into<Cow<'static, str>>>(name: T) -> Error {
54        Error::MissingEntity(name.into())
55    }
56
57    #[doc(hidden)]
58    pub fn incompatible<T: Into<Cow<'static, str>>>(desc: T) -> Error {
59        Error::Incompatible(desc.into())
60    }
61}
62
63impl fmt::Display for Error {
64    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
65        match self {
66            Error::MissingEntity(name) => {
67                f.write_fmt(format_args!("Expected entity `{}` is missing", name))
68            }
69            Error::Incompatible(reason) => f.write_str(reason),
70            Error::Io(e) => fmt::Display::fmt(e, f),
71            Error::Other(e) => fmt::Display::fmt(e, f),
72            _ => f.write_str("Unknown error"),
73        }
74    }
75}
76
77impl error::Error for Error {
78    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
79        match self {
80            Error::Io(e) => Some(&*e),
81            Error::Other(e) => Some(&**e),
82            _ => None,
83        }
84    }
85}
86
87impl From<io::Error> for Error {
88    fn from(e: io::Error) -> Self {
89        Error::Io(e)
90    }
91}
92
93impl From<num::ParseIntError> for Error {
94    fn from(e: num::ParseIntError) -> Self {
95        Error::Other(Box::new(e))
96    }
97}
98
99impl From<num::ParseFloatError> for Error {
100    fn from(e: num::ParseFloatError) -> Self {
101        Error::Other(Box::new(e))
102    }
103}
104
105impl From<ffi::NulError> for Error {
106    fn from(e: ffi::NulError) -> Self {
107        Error::Other(Box::new(e))
108    }
109}
110
111impl From<ffi::IntoStringError> for Error {
112    fn from(e: ffi::IntoStringError) -> Self {
113        Error::Other(Box::new(e))
114    }
115}
116
117impl From<string::ParseError> for Error {
118    fn from(e: string::ParseError) -> Self {
119        // `string::ParseError` is a type alias to `Never`,
120        // and since it is in stabilization right now,
121        // `heim` is affected by https://github.com/heim-rs/heim/issues/182
122        match e {}
123    }
124}
125
126impl From<string::FromUtf8Error> for Error {
127    fn from(e: string::FromUtf8Error) -> Self {
128        Error::Other(Box::new(e))
129    }
130}
131
132impl From<net::AddrParseError> for Error {
133    fn from(e: net::AddrParseError) -> Self {
134        Error::Other(Box::new(e))
135    }
136}
137
138impl<T> From<Box<T>> for Error
139where
140    T: error::Error + Send + 'static,
141{
142    fn from(e: Box<T>) -> Self {
143        Error::Other(e)
144    }
145}
146
147#[cfg(unix)]
148impl From<nix::Error> for Error {
149    fn from(e: nix::Error) -> Self {
150        Error::Other(Box::new(e))
151    }
152}