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}