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