use std::borrow::Cow;
use std::error;
use std::ffi::CStr;
use std::fmt;
use std::io;
use libc::c_int;
pub struct Error {
code: c_int,
os_error: Option<io::Error>,
}
impl fmt::Debug for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("Error")
.field("code", &self.code)
.field("message", &self.as_str())
.finish()
}
}
impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.as_str(), fmt)
}
}
impl error::Error for Error {}
impl Error {
pub(crate) fn new() -> Error {
let saved = io::Error::last_os_error();
let code = unsafe { crate::dw_sys::dwfl_errno() };
Error {
code,
os_error: saved.raw_os_error().filter(|&e| e != 0).map(|_| saved),
}
}
fn as_str(&self) -> Cow<'_, str> {
unsafe {
let s = crate::dw_sys::dwfl_errmsg(self.code);
if s.is_null() {
if let Some(ref os_error) = self.os_error {
return format!("{os_error}").into();
}
"unknown error".into()
} else {
CStr::from_ptr(s).to_string_lossy()
}
}
}
}