Skip to main content

windows_result/
win32_error.rs

1use super::*;
2
3/// An error or status code value returned by some operating system functions.
4#[repr(transparent)]
5#[derive(Copy, Clone, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
6#[must_use]
7pub struct WIN32_ERROR(pub u32);
8
9impl WIN32_ERROR {
10    /// Returns [`true`] if `self` is a success code.
11    #[inline]
12    pub const fn is_ok(self) -> bool {
13        self.0 == 0
14    }
15
16    /// Returns [`true`] if `self` is a failure code.
17    #[inline]
18    pub const fn is_err(self) -> bool {
19        !self.is_ok()
20    }
21
22    /// Maps a Win32 error code to an HRESULT value.
23    #[inline]
24    pub const fn to_hresult(self) -> HRESULT {
25        HRESULT(if self.0 as i32 <= 0 {
26            self.0
27        } else {
28            (self.0 & 0x0000_FFFF) | (7 << 16) | 0x8000_0000
29        } as i32)
30    }
31
32    /// Returns the Win32 error contained in `error`, if it represents one.
33    #[inline]
34    pub fn from_error(error: &Error) -> Option<Self> {
35        let hresult = error.code().0 as u32;
36
37        if ((hresult >> 16) & 0x7FF) == 7 {
38            Some(Self(hresult & 0xFFFF))
39        } else {
40            None
41        }
42    }
43
44    /// Converts the error to a [`Result`], treating a successful code as `Ok`.
45    #[inline]
46    pub fn ok(self) -> Result<()> {
47        self.to_hresult().ok()
48    }
49
50    /// Creates a new `WIN32_ERROR` from the Win32 error code returned by `GetLastError()`.
51    pub fn from_thread() -> Self {
52        Self(unsafe { GetLastError() })
53    }
54}
55
56impl From<WIN32_ERROR> for HRESULT {
57    fn from(value: WIN32_ERROR) -> Self {
58        value.to_hresult()
59    }
60}
61
62impl From<WIN32_ERROR> for Error {
63    fn from(value: WIN32_ERROR) -> Self {
64        value.to_hresult().into()
65    }
66}
67
68impl core::fmt::Display for WIN32_ERROR {
69    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
70        f.write_fmt(format_args!("{}", self.0))
71    }
72}
73
74impl core::fmt::Debug for WIN32_ERROR {
75    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
76        f.write_fmt(format_args!("WIN32_ERROR({self})"))
77    }
78}