rvs/
error.rs

1#![cfg_attr(feature = "cargo-clippy", allow(not_unsafe_ptr_arg_deref))]
2
3use std::fmt;
4use std::io;
5use std::ffi::CString;
6use libc::c_char;
7
8use rvs;
9
10#[derive(Debug)]
11pub struct Error {
12    pub message: Option<CString>,
13    pub kind: ErrorKind,
14}
15
16#[derive(Debug)]
17pub enum ErrorKind {
18    None,
19    Rvs(rvs::Error),
20    Io(io::Error),
21}
22
23impl Error {
24    pub fn new(kind: ErrorKind) -> Error {
25        Error {
26            message: None,
27            kind,
28        }
29    }
30
31    pub fn is_err(&self) -> bool {
32        match self.kind {
33            ErrorKind::None => false,
34            ErrorKind::Rvs(_) | ErrorKind::Io(_) => true,
35        }
36    }
37}
38
39impl fmt::Display for Error {
40    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
41        match self.kind {
42            ErrorKind::None => write!(f, "no error"),
43            ErrorKind::Rvs(ref e) => e.fmt(f),
44            ErrorKind::Io(ref e) => e.fmt(f),
45        }
46    }
47}
48
49impl From<rvs::Error> for ErrorKind {
50    fn from(err: rvs::Error) -> ErrorKind {
51        ErrorKind::Rvs(err)
52    }
53}
54
55#[no_mangle]
56pub extern "C" fn rvs_error_new() -> *mut Error {
57    Box::into_raw(Box::new(Error::new(ErrorKind::None)))
58}
59
60#[no_mangle]
61pub extern "C" fn rvs_error_free(err: *mut Error) {
62    unsafe {
63        Box::from_raw(err);
64    }
65}
66
67#[no_mangle]
68pub extern "C" fn rvs_error_message(err: *mut Error) -> *const c_char {
69    let err = unsafe { &mut *err };
70    let cmsg = match CString::new(format!("{}", err)) {
71        Ok(msg) => msg,
72        Err(_) => CString::new("Failed to allocate CString. This shouldn't happen").unwrap(),
73    };
74    let p = cmsg.as_ptr();
75    err.message = Some(cmsg);
76    p
77}
78
79#[no_mangle]
80pub extern "C" fn rvs_error_test(err: *const Error) -> bool {
81    let err = unsafe { &*err };
82
83    err.is_err()
84}