1 use core::fmt::Debug;
2 
3 newtype_enum! {
4 /// UEFI uses status codes in order to report successes, errors, and warnings.
5 ///
6 /// The spec allows implementation-specific status codes, so the `Status`
7 /// constants are not a comprehensive list of all possible values.
8 #[must_use]
9 pub enum Status: usize => {
10     /// The operation completed successfully.
11     SUCCESS                 =  0,
12 
13     /// The string contained characters that could not be rendered and were skipped.
14     WARN_UNKNOWN_GLYPH      =  1,
15     /// The handle was closed, but the file was not deleted.
16     WARN_DELETE_FAILURE     =  2,
17     /// The handle was closed, but the data to the file was not flushed properly.
18     WARN_WRITE_FAILURE      =  3,
19     /// The resulting buffer was too small, and the data was truncated.
20     WARN_BUFFER_TOO_SMALL   =  4,
21     /// The data has not been updated within the timeframe set by local policy.
22     WARN_STALE_DATA         =  5,
23     /// The resulting buffer contains UEFI-compliant file system.
24     WARN_FILE_SYSTEM        =  6,
25     /// The operation will be processed across a system reset.
26     WARN_RESET_REQUIRED     =  7,
27 
28     /// The image failed to load.
29     LOAD_ERROR              = Self::ERROR_BIT |  1,
30     /// A parameter was incorrect.
31     INVALID_PARAMETER       = Self::ERROR_BIT |  2,
32     /// The operation is not supported.
33     UNSUPPORTED             = Self::ERROR_BIT |  3,
34     /// The buffer was not the proper size for the request.
35     BAD_BUFFER_SIZE         = Self::ERROR_BIT |  4,
36     /// The buffer is not large enough to hold the requested data.
37     /// The required buffer size is returned in the appropriate parameter.
38     BUFFER_TOO_SMALL        = Self::ERROR_BIT |  5,
39     /// There is no data pending upon return.
40     NOT_READY               = Self::ERROR_BIT |  6,
41     /// The physical device reported an error while attempting the operation.
42     DEVICE_ERROR            = Self::ERROR_BIT |  7,
43     /// The device cannot be written to.
44     WRITE_PROTECTED         = Self::ERROR_BIT |  8,
45     /// A resource has run out.
46     OUT_OF_RESOURCES        = Self::ERROR_BIT |  9,
47     /// An inconstency was detected on the file system.
48     VOLUME_CORRUPTED        = Self::ERROR_BIT | 10,
49     /// There is no more space on the file system.
50     VOLUME_FULL             = Self::ERROR_BIT | 11,
51     /// The device does not contain any medium to perform the operation.
52     NO_MEDIA                = Self::ERROR_BIT | 12,
53     /// The medium in the device has changed since the last access.
54     MEDIA_CHANGED           = Self::ERROR_BIT | 13,
55     /// The item was not found.
56     NOT_FOUND               = Self::ERROR_BIT | 14,
57     /// Access was denied.
58     ACCESS_DENIED           = Self::ERROR_BIT | 15,
59     /// The server was not found or did not respond to the request.
60     NO_RESPONSE             = Self::ERROR_BIT | 16,
61     /// A mapping to a device does not exist.
62     NO_MAPPING              = Self::ERROR_BIT | 17,
63     /// The timeout time expired.
64     TIMEOUT                 = Self::ERROR_BIT | 18,
65     /// The protocol has not been started.
66     NOT_STARTED             = Self::ERROR_BIT | 19,
67     /// The protocol has already been started.
68     ALREADY_STARTED         = Self::ERROR_BIT | 20,
69     /// The operation was aborted.
70     ABORTED                 = Self::ERROR_BIT | 21,
71     /// An ICMP error occurred during the network operation.
72     ICMP_ERROR              = Self::ERROR_BIT | 22,
73     /// A TFTP error occurred during the network operation.
74     TFTP_ERROR              = Self::ERROR_BIT | 23,
75     /// A protocol error occurred during the network operation.
76     PROTOCOL_ERROR          = Self::ERROR_BIT | 24,
77     /// The function encountered an internal version that was
78     /// incompatible with a version requested by the caller.
79     INCOMPATIBLE_VERSION    = Self::ERROR_BIT | 25,
80     /// The function was not performed due to a security violation.
81     SECURITY_VIOLATION      = Self::ERROR_BIT | 26,
82     /// A CRC error was detected.
83     CRC_ERROR               = Self::ERROR_BIT | 27,
84     /// Beginning or end of media was reached
85     END_OF_MEDIA            = Self::ERROR_BIT | 28,
86     /// The end of the file was reached.
87     END_OF_FILE             = Self::ERROR_BIT | 31,
88     /// The language specified was invalid.
89     INVALID_LANGUAGE        = Self::ERROR_BIT | 32,
90     /// The security status of the data is unknown or compromised and
91     /// the data must be updated or replaced to restore a valid security status.
92     COMPROMISED_DATA        = Self::ERROR_BIT | 33,
93     /// There is an address conflict address allocation
94     IP_ADDRESS_CONFLICT     = Self::ERROR_BIT | 34,
95     /// A HTTP error occurred during the network operation.
96     HTTP_ERROR              = Self::ERROR_BIT | 35,
97 }}
98 
99 impl Status {
100     /// Bit indicating that an UEFI status code is an error.
101     pub const ERROR_BIT: usize = 1 << (core::mem::size_of::<usize>() * 8 - 1);
102 
103     /// Returns true if status code indicates success.
104     #[inline]
105     #[must_use]
is_success(self) -> bool106     pub fn is_success(self) -> bool {
107         self == Self::SUCCESS
108     }
109 
110     /// Returns true if status code indicates a warning.
111     #[inline]
112     #[must_use]
is_warning(self) -> bool113     pub fn is_warning(self) -> bool {
114         (self != Self::SUCCESS) && (self.0 & Self::ERROR_BIT == 0)
115     }
116 
117     /// Returns true if the status code indicates an error.
118     #[inline]
119     #[must_use]
is_error(self) -> bool120     pub const fn is_error(self) -> bool {
121         self.0 & Self::ERROR_BIT != 0
122     }
123 }
124 
125 impl core::fmt::Display for Status {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result126     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
127         Debug::fmt(self, f)
128     }
129 }
130