| 1 | use std::ffi::{CString, CStr}; |
| 2 | |
| 3 | /// A `dlerror` error. |
| 4 | pub struct DlDescription(pub(crate) CString); |
| 5 | |
| 6 | impl std::fmt::Debug for DlDescription { |
| 7 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
| 8 | std::fmt::Debug::fmt(&self.0, f) |
| 9 | } |
| 10 | } |
| 11 | |
| 12 | impl From<&CStr> for DlDescription { |
| 13 | fn from(value: &CStr) -> Self { |
| 14 | Self(value.into()) |
| 15 | } |
| 16 | } |
| 17 | |
| 18 | /// A Windows API error. |
| 19 | pub struct WindowsError(pub(crate) std::io::Error); |
| 20 | |
| 21 | impl std::fmt::Debug for WindowsError { |
| 22 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
| 23 | std::fmt::Debug::fmt(&self.0, f) |
| 24 | } |
| 25 | } |
| 26 | |
| 27 | /// Errors. |
| 28 | #[derive (Debug)] |
| 29 | #[non_exhaustive ] |
| 30 | pub enum Error { |
| 31 | /// The `dlopen` call failed. |
| 32 | DlOpen { |
| 33 | /// The source error. |
| 34 | desc: DlDescription |
| 35 | }, |
| 36 | /// The `dlopen` call failed and system did not report an error. |
| 37 | DlOpenUnknown, |
| 38 | /// The `dlsym` call failed. |
| 39 | DlSym { |
| 40 | /// The source error. |
| 41 | desc: DlDescription |
| 42 | }, |
| 43 | /// The `dlsym` call failed and system did not report an error. |
| 44 | DlSymUnknown, |
| 45 | /// The `dlclose` call failed. |
| 46 | DlClose { |
| 47 | /// The source error. |
| 48 | desc: DlDescription |
| 49 | }, |
| 50 | /// The `dlclose` call failed and system did not report an error. |
| 51 | DlCloseUnknown, |
| 52 | /// The `LoadLibraryW` call failed. |
| 53 | LoadLibraryExW { |
| 54 | /// The source error. |
| 55 | source: WindowsError |
| 56 | }, |
| 57 | /// The `LoadLibraryW` call failed and system did not report an error. |
| 58 | LoadLibraryExWUnknown, |
| 59 | /// The `GetModuleHandleExW` call failed. |
| 60 | GetModuleHandleExW { |
| 61 | /// The source error. |
| 62 | source: WindowsError |
| 63 | }, |
| 64 | /// The `GetModuleHandleExW` call failed and system did not report an error. |
| 65 | GetModuleHandleExWUnknown, |
| 66 | /// The `GetProcAddress` call failed. |
| 67 | GetProcAddress { |
| 68 | /// The source error. |
| 69 | source: WindowsError |
| 70 | }, |
| 71 | /// The `GetProcAddressUnknown` call failed and system did not report an error. |
| 72 | GetProcAddressUnknown, |
| 73 | /// The `FreeLibrary` call failed. |
| 74 | FreeLibrary { |
| 75 | /// The source error. |
| 76 | source: WindowsError |
| 77 | }, |
| 78 | /// The `FreeLibrary` call failed and system did not report an error. |
| 79 | FreeLibraryUnknown, |
| 80 | /// The requested type cannot possibly work. |
| 81 | IncompatibleSize, |
| 82 | /// Could not create a new CString. |
| 83 | CreateCString { |
| 84 | /// The source error. |
| 85 | source: std::ffi::NulError |
| 86 | }, |
| 87 | /// Could not create a new CString from bytes with trailing null. |
| 88 | CreateCStringWithTrailing { |
| 89 | /// The source error. |
| 90 | source: std::ffi::FromBytesWithNulError |
| 91 | }, |
| 92 | } |
| 93 | |
| 94 | impl std::error::Error for Error { |
| 95 | fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { |
| 96 | use Error::*; |
| 97 | match *self { |
| 98 | CreateCString { ref source: &NulError } => Some(source), |
| 99 | CreateCStringWithTrailing { ref source: &FromBytesWithNulError } => Some(source), |
| 100 | LoadLibraryExW { ref source: &WindowsError } => Some(&source.0), |
| 101 | GetModuleHandleExW { ref source: &WindowsError } => Some(&source.0), |
| 102 | GetProcAddress { ref source: &WindowsError } => Some(&source.0), |
| 103 | FreeLibrary { ref source: &WindowsError } => Some(&source.0), |
| 104 | _ => None, |
| 105 | } |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | impl std::fmt::Display for Error { |
| 110 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { |
| 111 | use Error::*; |
| 112 | match *self { |
| 113 | DlOpen { ref desc } => write!(f, " {}" , desc.0.to_string_lossy()), |
| 114 | DlOpenUnknown => write!(f, "dlopen failed, but system did not report the error" ), |
| 115 | DlSym { ref desc } => write!(f, " {}" , desc.0.to_string_lossy()), |
| 116 | DlSymUnknown => write!(f, "dlsym failed, but system did not report the error" ), |
| 117 | DlClose { ref desc } => write!(f, " {}" , desc.0.to_string_lossy()), |
| 118 | DlCloseUnknown => write!(f, "dlclose failed, but system did not report the error" ), |
| 119 | LoadLibraryExW { .. } => write!(f, "LoadLibraryExW failed" ), |
| 120 | LoadLibraryExWUnknown => |
| 121 | write!(f, "LoadLibraryExW failed, but system did not report the error" ), |
| 122 | GetModuleHandleExW { .. } => write!(f, "GetModuleHandleExW failed" ), |
| 123 | GetModuleHandleExWUnknown => |
| 124 | write!(f, "GetModuleHandleExWUnknown failed, but system did not report the error" ), |
| 125 | GetProcAddress { .. } => write!(f, "GetProcAddress failed" ), |
| 126 | GetProcAddressUnknown => |
| 127 | write!(f, "GetProcAddress failed, but system did not report the error" ), |
| 128 | FreeLibrary { .. } => write!(f, "FreeLibrary failed" ), |
| 129 | FreeLibraryUnknown => |
| 130 | write!(f, "FreeLibrary failed, but system did not report the error" ), |
| 131 | CreateCString { .. } => write!(f, "could not create a C string from bytes" ), |
| 132 | CreateCStringWithTrailing { .. } => |
| 133 | write!(f, "could not create a C string from bytes with trailing null" ), |
| 134 | IncompatibleSize => write!(f, "requested type cannot possibly work" ), |
| 135 | } |
| 136 | } |
| 137 | } |
| 138 | |