cubeb_core/
error.rs

1use ffi;
2use std::ffi::NulError;
3use std::os::raw::c_int;
4use std::{error, fmt};
5
6pub type Result<T> = ::std::result::Result<T, Error>;
7
8/// An enumeration of possible errors that can happen when working with cubeb.
9#[derive(PartialEq, Eq, Clone, Debug, Copy)]
10pub enum ErrorCode {
11    /// GenericError
12    Error,
13    /// Requested format is invalid
14    InvalidFormat,
15    /// Requested parameter is invalid
16    InvalidParameter,
17    /// Requested operation is not supported
18    NotSupported,
19    /// Requested device is unavailable
20    DeviceUnavailable,
21}
22
23#[derive(Clone, Copy, Debug, PartialEq, Eq)]
24pub struct Error {
25    code: ErrorCode,
26}
27
28impl Error {
29    #[allow(clippy::self_named_constructors)]
30    pub fn error() -> Self {
31        Error {
32            code: ErrorCode::Error,
33        }
34    }
35    pub fn invalid_format() -> Self {
36        Error {
37            code: ErrorCode::InvalidFormat,
38        }
39    }
40    pub fn invalid_parameter() -> Self {
41        Error {
42            code: ErrorCode::InvalidParameter,
43        }
44    }
45    pub fn not_supported() -> Self {
46        Error {
47            code: ErrorCode::NotSupported,
48        }
49    }
50    pub fn device_unavailable() -> Self {
51        Error {
52            code: ErrorCode::DeviceUnavailable,
53        }
54    }
55
56    pub fn from_raw(code: c_int) -> Error {
57        let code = match code {
58            ffi::CUBEB_ERROR_INVALID_FORMAT => ErrorCode::InvalidFormat,
59            ffi::CUBEB_ERROR_INVALID_PARAMETER => ErrorCode::InvalidParameter,
60            ffi::CUBEB_ERROR_NOT_SUPPORTED => ErrorCode::NotSupported,
61            ffi::CUBEB_ERROR_DEVICE_UNAVAILABLE => ErrorCode::DeviceUnavailable,
62            // Everything else is just the generic error
63            _ => ErrorCode::Error,
64        };
65
66        Error { code }
67    }
68
69    pub fn code(&self) -> ErrorCode {
70        self.code
71    }
72
73    pub fn raw_code(&self) -> c_int {
74        match self.code {
75            ErrorCode::Error => ffi::CUBEB_ERROR,
76            ErrorCode::InvalidFormat => ffi::CUBEB_ERROR_INVALID_FORMAT,
77            ErrorCode::InvalidParameter => ffi::CUBEB_ERROR_INVALID_PARAMETER,
78            ErrorCode::NotSupported => ffi::CUBEB_ERROR_NOT_SUPPORTED,
79            ErrorCode::DeviceUnavailable => ffi::CUBEB_ERROR_DEVICE_UNAVAILABLE,
80        }
81    }
82}
83
84impl Default for Error {
85    fn default() -> Self {
86        Error::error()
87    }
88}
89
90impl error::Error for Error {
91    fn description(&self) -> &str {
92        match self.code {
93            ErrorCode::Error => "Error",
94            ErrorCode::InvalidFormat => "Invalid format",
95            ErrorCode::InvalidParameter => "Invalid parameter",
96            ErrorCode::NotSupported => "Not supported",
97            ErrorCode::DeviceUnavailable => "Device unavailable",
98        }
99    }
100}
101
102impl fmt::Display for Error {
103    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
104        write!(f, "{self:?}")
105    }
106}
107
108impl From<ErrorCode> for Error {
109    fn from(code: ErrorCode) -> Error {
110        Error { code }
111    }
112}
113
114impl From<NulError> for Error {
115    fn from(_: NulError) -> Error {
116        Error::from_raw(ffi::CUBEB_ERROR)
117    }
118}
119
120#[cfg(test)]
121mod tests {
122    use super::*;
123    use ffi;
124
125    #[test]
126    fn test_from_raw() {
127        macro_rules! test {
128            ( $($raw:ident => $err:ident),* ) => {{
129                $(
130                    let e = Error::from_raw(ffi::$raw);
131                    assert_eq!(e.raw_code(), ffi::$raw);
132                    assert_eq!(e.code(), ErrorCode::$err);
133                )*
134            }};
135        }
136        test!(CUBEB_ERROR => Error,
137              CUBEB_ERROR_INVALID_FORMAT => InvalidFormat,
138              CUBEB_ERROR_INVALID_PARAMETER => InvalidParameter,
139              CUBEB_ERROR_NOT_SUPPORTED => NotSupported,
140              CUBEB_ERROR_DEVICE_UNAVAILABLE => DeviceUnavailable
141        );
142    }
143
144    #[test]
145    fn test_from_error_code() {
146        macro_rules! test {
147            ( $($raw:ident => $err:ident),* ) => {{
148                $(
149                    let e = Error::from(ErrorCode::$err);
150                    assert_eq!(e.raw_code(), ffi::$raw);
151                    assert_eq!(e.code(), ErrorCode::$err);
152                )*
153            }};
154        }
155        test!(CUBEB_ERROR => Error,
156              CUBEB_ERROR_INVALID_FORMAT => InvalidFormat,
157              CUBEB_ERROR_INVALID_PARAMETER => InvalidParameter,
158              CUBEB_ERROR_NOT_SUPPORTED => NotSupported,
159              CUBEB_ERROR_DEVICE_UNAVAILABLE => DeviceUnavailable
160        );
161    }
162}