libloading/
error.rs

1use alloc::ffi::CString;
2use core::ffi::CStr;
3
4/// A `dlerror` error.
5pub struct DlError(pub(crate) CString);
6
7impl core::error::Error for DlError {}
8
9impl core::fmt::Debug for DlError {
10    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
11        core::fmt::Debug::fmt(&self.0, f)
12    }
13}
14
15impl core::fmt::Display for DlError {
16    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
17        f.write_str(&self.0.to_string_lossy())
18    }
19}
20
21impl From<&CStr> for DlError {
22    fn from(value: &CStr) -> Self {
23        Self(value.into())
24    }
25}
26
27/// A Windows API error.
28#[derive(Copy, Clone)]
29pub struct WindowsError(pub(crate) i32);
30
31impl core::error::Error for WindowsError { }
32
33impl core::fmt::Debug for WindowsError {
34    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
35        core::fmt::Debug::fmt(&self.0, f)
36    }
37}
38
39impl core::fmt::Display for WindowsError {
40    #[cfg(feature = "std")]
41    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
42        let error = std::io::Error::from_raw_os_error(self.0);
43        core::fmt::Display::fmt(&error, f)
44    }
45    #[cfg(not(feature = "std"))]
46    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
47        f.write_fmt(format_args!("OS error {}", self.0))
48    }
49}
50
51/// Errors.
52#[derive(Debug)]
53#[non_exhaustive]
54pub enum Error {
55    /// The `dlopen` call failed.
56    DlOpen {
57        /// The source error.
58        source: DlError,
59    },
60    /// The `dlopen` call failed and system did not report an error.
61    DlOpenUnknown,
62    /// The `dlsym` call failed.
63    DlSym {
64        /// The source error.
65        source: DlError,
66    },
67    /// The `dlsym` call failed and system did not report an error.
68    DlSymUnknown,
69    /// The `dlclose` call failed.
70    DlClose {
71        /// The source error.
72        source: DlError,
73    },
74    /// The `dlclose` call failed and system did not report an error.
75    DlCloseUnknown,
76    /// The `LoadLibraryW` call failed.
77    LoadLibraryExW {
78        /// The source error.
79        source: WindowsError,
80    },
81    /// The `LoadLibraryW` call failed and system did not report an error.
82    LoadLibraryExWUnknown,
83    /// The `GetModuleHandleExW` call failed.
84    GetModuleHandleExW {
85        /// The source error.
86        source: WindowsError,
87    },
88    /// The `GetModuleHandleExW` call failed and system did not report an error.
89    GetModuleHandleExWUnknown,
90    /// The `GetProcAddress` call failed.
91    GetProcAddress {
92        /// The source error.
93        source: WindowsError,
94    },
95    /// The `GetProcAddressUnknown` call failed and system did not report an error.
96    GetProcAddressUnknown,
97    /// The `FreeLibrary` call failed.
98    FreeLibrary {
99        /// The source error.
100        source: WindowsError,
101    },
102    /// The `FreeLibrary` call failed and system did not report an error.
103    FreeLibraryUnknown,
104    /// The requested type cannot possibly work.
105    IncompatibleSize,
106    /// Input symbol of filename contains interior 0/null elements.
107    InteriorZeroElements,
108}
109
110impl core::error::Error for Error {
111    fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
112        use Error::*;
113        match self {
114            LoadLibraryExW { source }
115            | GetModuleHandleExW { source }
116            | GetProcAddress { source }
117            | FreeLibrary { source } => Some(source),
118            DlOpen { source } | DlSym { source } | DlClose { source } => Some(source),
119            DlOpenUnknown
120            | DlSymUnknown
121            | DlCloseUnknown
122            | LoadLibraryExWUnknown
123            | GetModuleHandleExWUnknown
124            | GetProcAddressUnknown
125            | FreeLibraryUnknown
126            | IncompatibleSize
127            | InteriorZeroElements => None,
128        }
129    }
130}
131
132impl core::fmt::Display for Error {
133    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
134        use Error::*;
135        match *self {
136            DlOpen { .. } => write!(f, "dlopen failed"),
137            DlOpenUnknown => write!(f, "dlopen failed, but system did not report the error"),
138            DlSym { .. } => write!(f, "dlsym failed"),
139            DlSymUnknown => write!(f, "dlsym failed, but system did not report the error"),
140            DlClose { .. } => write!(f, "dlclose failed"),
141            DlCloseUnknown => write!(f, "dlclose failed, but system did not report the error"),
142            LoadLibraryExW { .. } => write!(f, "LoadLibraryExW failed"),
143            LoadLibraryExWUnknown => write!(
144                f,
145                "LoadLibraryExW failed, but system did not report the error"
146            ),
147            GetModuleHandleExW { .. } => write!(f, "GetModuleHandleExW failed"),
148            GetModuleHandleExWUnknown => write!(
149                f,
150                "GetModuleHandleExWUnknown failed, but system did not report the error"
151            ),
152            GetProcAddress { .. } => write!(f, "GetProcAddress failed"),
153            GetProcAddressUnknown => write!(
154                f,
155                "GetProcAddress failed, but system did not report the error"
156            ),
157            FreeLibrary { .. } => write!(f, "FreeLibrary failed"),
158            FreeLibraryUnknown => {
159                write!(f, "FreeLibrary failed, but system did not report the error")
160            }
161            InteriorZeroElements => write!(f, "interior zero element in parameter"),
162            IncompatibleSize => write!(f, "requested type cannot possibly work"),
163        }
164    }
165}