Revision control

Copy as Markdown

Other Tools

use ffi;
use std::ffi::NulError;
use std::os::raw::c_int;
use std::{error, fmt};
pub type Result<T> = ::std::result::Result<T, Error>;
/// An enumeration of possible errors that can happen when working with cubeb.
#[derive(PartialEq, Eq, Clone, Debug, Copy)]
pub enum ErrorCode {
/// GenericError
Error,
/// Requested format is invalid
InvalidFormat,
/// Requested parameter is invalid
InvalidParameter,
/// Requested operation is not supported
NotSupported,
/// Requested device is unavailable
DeviceUnavailable,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Error {
code: ErrorCode,
}
impl Error {
#[allow(clippy::self_named_constructors)]
pub fn error() -> Self {
Error {
code: ErrorCode::Error,
}
}
pub fn invalid_format() -> Self {
Error {
code: ErrorCode::InvalidFormat,
}
}
pub fn invalid_parameter() -> Self {
Error {
code: ErrorCode::InvalidParameter,
}
}
pub fn not_supported() -> Self {
Error {
code: ErrorCode::NotSupported,
}
}
pub fn device_unavailable() -> Self {
Error {
code: ErrorCode::DeviceUnavailable,
}
}
pub fn from_raw(code: c_int) -> Error {
let code = match code {
ffi::CUBEB_ERROR_INVALID_FORMAT => ErrorCode::InvalidFormat,
ffi::CUBEB_ERROR_INVALID_PARAMETER => ErrorCode::InvalidParameter,
ffi::CUBEB_ERROR_NOT_SUPPORTED => ErrorCode::NotSupported,
ffi::CUBEB_ERROR_DEVICE_UNAVAILABLE => ErrorCode::DeviceUnavailable,
// Everything else is just the generic error
_ => ErrorCode::Error,
};
Error { code }
}
pub fn code(&self) -> ErrorCode {
self.code
}
pub fn raw_code(&self) -> c_int {
match self.code {
ErrorCode::Error => ffi::CUBEB_ERROR,
ErrorCode::InvalidFormat => ffi::CUBEB_ERROR_INVALID_FORMAT,
ErrorCode::InvalidParameter => ffi::CUBEB_ERROR_INVALID_PARAMETER,
ErrorCode::NotSupported => ffi::CUBEB_ERROR_NOT_SUPPORTED,
ErrorCode::DeviceUnavailable => ffi::CUBEB_ERROR_DEVICE_UNAVAILABLE,
}
}
}
impl Default for Error {
fn default() -> Self {
Error::error()
}
}
impl error::Error for Error {
fn description(&self) -> &str {
match self.code {
ErrorCode::Error => "Error",
ErrorCode::InvalidFormat => "Invalid format",
ErrorCode::InvalidParameter => "Invalid parameter",
ErrorCode::NotSupported => "Not supported",
ErrorCode::DeviceUnavailable => "Device unavailable",
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self)
}
}
impl From<ErrorCode> for Error {
fn from(code: ErrorCode) -> Error {
Error { code }
}
}
impl From<NulError> for Error {
fn from(_: NulError) -> Error {
Error::from_raw(ffi::CUBEB_ERROR)
}
}
#[cfg(test)]
mod tests {
use super::*;
use ffi;
#[test]
fn test_from_raw() {
macro_rules! test {
( $($raw:ident => $err:ident),* ) => {{
$(
let e = Error::from_raw(ffi::$raw);
assert_eq!(e.raw_code(), ffi::$raw);
assert_eq!(e.code(), ErrorCode::$err);
)*
}};
}
test!(CUBEB_ERROR => Error,
CUBEB_ERROR_INVALID_FORMAT => InvalidFormat,
CUBEB_ERROR_INVALID_PARAMETER => InvalidParameter,
CUBEB_ERROR_NOT_SUPPORTED => NotSupported,
CUBEB_ERROR_DEVICE_UNAVAILABLE => DeviceUnavailable
);
}
#[test]
fn test_from_error_code() {
macro_rules! test {
( $($raw:ident => $err:ident),* ) => {{
$(
let e = Error::from(ErrorCode::$err);
assert_eq!(e.raw_code(), ffi::$raw);
assert_eq!(e.code(), ErrorCode::$err);
)*
}};
}
test!(CUBEB_ERROR => Error,
CUBEB_ERROR_INVALID_FORMAT => InvalidFormat,
CUBEB_ERROR_INVALID_PARAMETER => InvalidParameter,
CUBEB_ERROR_NOT_SUPPORTED => NotSupported,
CUBEB_ERROR_DEVICE_UNAVAILABLE => DeviceUnavailable
);
}
}