use alloc::ffi::CString;
use core::ffi::CStr;
pub struct DlError(pub(crate) CString);
impl core::error::Error for DlError {}
impl core::fmt::Debug for DlError {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
core::fmt::Debug::fmt(&self.0, f)
}
}
impl core::fmt::Display for DlError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_str(&self.0.to_string_lossy())
}
}
impl From<&CStr> for DlError {
fn from(value: &CStr) -> Self {
Self(value.into())
}
}
#[derive(Copy, Clone)]
pub struct WindowsError(pub(crate) i32);
impl core::error::Error for WindowsError { }
impl core::fmt::Debug for WindowsError {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
core::fmt::Debug::fmt(&self.0, f)
}
}
impl core::fmt::Display for WindowsError {
#[cfg(feature = "std")]
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let error = std::io::Error::from_raw_os_error(self.0);
core::fmt::Display::fmt(&error, f)
}
#[cfg(not(feature = "std"))]
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_fmt(format_args!("OS error {}", self.0))
}
}
#[derive(Debug)]
#[non_exhaustive]
pub enum Error {
DlOpen {
source: DlError,
},
DlOpenUnknown,
DlSym {
source: DlError,
},
DlSymUnknown,
DlClose {
source: DlError,
},
DlCloseUnknown,
LoadLibraryExW {
source: WindowsError,
},
LoadLibraryExWUnknown,
GetModuleHandleExW {
source: WindowsError,
},
GetModuleHandleExWUnknown,
GetProcAddress {
source: WindowsError,
},
GetProcAddressUnknown,
FreeLibrary {
source: WindowsError,
},
FreeLibraryUnknown,
IncompatibleSize,
InteriorZeroElements,
}
impl core::error::Error for Error {
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
use Error::*;
match self {
LoadLibraryExW { source }
| GetModuleHandleExW { source }
| GetProcAddress { source }
| FreeLibrary { source } => Some(source),
DlOpen { source } | DlSym { source } | DlClose { source } => Some(source),
DlOpenUnknown
| DlSymUnknown
| DlCloseUnknown
| LoadLibraryExWUnknown
| GetModuleHandleExWUnknown
| GetProcAddressUnknown
| FreeLibraryUnknown
| IncompatibleSize
| InteriorZeroElements => None,
}
}
}
impl core::fmt::Display for Error {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
use Error::*;
match *self {
DlOpen { .. } => write!(f, "dlopen failed"),
DlOpenUnknown => write!(f, "dlopen failed, but system did not report the error"),
DlSym { .. } => write!(f, "dlsym failed"),
DlSymUnknown => write!(f, "dlsym failed, but system did not report the error"),
DlClose { .. } => write!(f, "dlclose failed"),
DlCloseUnknown => write!(f, "dlclose failed, but system did not report the error"),
LoadLibraryExW { .. } => write!(f, "LoadLibraryExW failed"),
LoadLibraryExWUnknown => write!(
f,
"LoadLibraryExW failed, but system did not report the error"
),
GetModuleHandleExW { .. } => write!(f, "GetModuleHandleExW failed"),
GetModuleHandleExWUnknown => write!(
f,
"GetModuleHandleExWUnknown failed, but system did not report the error"
),
GetProcAddress { .. } => write!(f, "GetProcAddress failed"),
GetProcAddressUnknown => write!(
f,
"GetProcAddress failed, but system did not report the error"
),
FreeLibrary { .. } => write!(f, "FreeLibrary failed"),
FreeLibraryUnknown => {
write!(f, "FreeLibrary failed, but system did not report the error")
}
InteriorZeroElements => write!(f, "interior zero element in parameter"),
IncompatibleSize => write!(f, "requested type cannot possibly work"),
}
}
}