diff --git a/cowslice/src/error.rs b/cowslice/src/error.rs new file mode 100644 index 0000000..df468c7 --- /dev/null +++ b/cowslice/src/error.rs @@ -0,0 +1,41 @@ +use super::*; +use std::{error, fmt}; +use std::ffi::CStr; + +/// A `libcow` error object. +#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[repr(transparent)] +pub struct Error(i32); + +impl Error +{ + /// The last error in `libcow`. + #[inline(always)] pub fn last() -> Self + { + Self(unsafe {ffi::cow_err()}) + } +} + +impl error::Error for Error{} +impl fmt::Display for Error +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result + { + const DEFAULT: &'static [u8] = b"unknown\0"; // must be `nul`'d + let cstr = unsafe { + let ptr = ffi::cow_err_msg(self.0); + if ptr.is_null() { + CStr::from_bytes_with_nul_unchecked(DEFAULT) + } else { + let ptr = *ptr; + if ptr.is_null() { + CStr::from_bytes_with_nul_unchecked(DEFAULT) + } else { + CStr::from_ptr(ptr as *const i8) + } + } + }; + write!(f, "{}", cstr.to_string_lossy()) + } +} + diff --git a/cowslice/src/lib.rs b/cowslice/src/lib.rs index 2945950..5726c79 100644 --- a/cowslice/src/lib.rs +++ b/cowslice/src/lib.rs @@ -3,15 +3,13 @@ mod ffi; +pub mod error; +pub use error::Error; + #[cfg(test)] mod tests { - #[test] - fn it_works() { - assert_eq!(2 + 2, 4); - } #[test] fn link_works() { - unsafe { let raw_h = super::ffi::cow_create(100); assert_ne!(raw_h as usize, 0);