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 {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result7     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 {
from(value: &CStr) -> Self13     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 {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result22     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 {
source(&self) -> Option<&(dyn std::error::Error + 'static)>95     fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
96         use Error::*;
97         match *self {
98             CreateCString { ref source } => Some(source),
99             CreateCStringWithTrailing { ref source } => Some(source),
100             LoadLibraryExW { ref source } => Some(&source.0),
101             GetProcAddress { ref source } => Some(&source.0),
102             FreeLibrary { ref source } => Some(&source.0),
103             _ => None,
104         }
105     }
106 }
107 
108 impl std::fmt::Display for Error {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result109     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
110         use Error::*;
111         match *self {
112             DlOpen { ref desc } => write!(f, "{}", desc.0.to_string_lossy()),
113             DlOpenUnknown => write!(f, "dlopen failed, but system did not report the error"),
114             DlSym { ref desc } => write!(f, "{}", desc.0.to_string_lossy()),
115             DlSymUnknown => write!(f, "dlsym failed, but system did not report the error"),
116             DlClose { ref desc } => write!(f, "{}", desc.0.to_string_lossy()),
117             DlCloseUnknown => write!(f, "dlclose failed, but system did not report the error"),
118             LoadLibraryExW { .. } => write!(f, "LoadLibraryExW failed"),
119             LoadLibraryExWUnknown =>
120                 write!(f, "LoadLibraryExW failed, but system did not report the error"),
121             GetModuleHandleExW { .. } => write!(f, "GetModuleHandleExW failed"),
122             GetModuleHandleExWUnknown =>
123                 write!(f, "GetModuleHandleExWUnknown failed, but system did not report the error"),
124             GetProcAddress { .. } => write!(f, "GetProcAddress failed"),
125             GetProcAddressUnknown =>
126                 write!(f, "GetProcAddress failed, but system did not report the error"),
127             FreeLibrary { .. } => write!(f, "FreeLibrary failed"),
128             FreeLibraryUnknown =>
129                 write!(f, "FreeLibrary failed, but system did not report the error"),
130             CreateCString { .. } => write!(f, "could not create a C string from bytes"),
131             CreateCStringWithTrailing { .. } =>
132                 write!(f, "could not create a C string from bytes with trailing null"),
133             IncompatibleSize => write!(f, "requested type cannot possibly work"),
134         }
135     }
136 }
137