libloading/
error.rs

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