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