1use std::ffi::CString;
2
3/// A `dlerror` error.
4pub struct DlDescription(pub(crate) CString);
5
6impl 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/// A Windows API error.
13pub struct WindowsError(pub(crate) std::io::Error);
14
15impl std::fmt::Debug for WindowsError {
16    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]
24pub 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    LoadLibraryExW {
48        /// The source error.
49        source: WindowsError
50    },
51    /// The `LoadLibraryW` call failed and system did not report an error.
52    LoadLibraryExWUnknown,
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
88impl std::error::Error for Error {
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            LoadLibraryExW { 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
102impl std::fmt::Display for Error {
103    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            LoadLibraryExW { .. } => write!(f, "LoadLibraryExW failed"),
113            LoadLibraryExWUnknown =>
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