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