xref: /aosp_15_r20/bootable/libbootloader/gbl/liberror/src/lib.rs (revision 5225e6b173e52d2efc6bcf950c27374fd72adabc)
1*5225e6b1SAndroid Build Coastguard Worker // Copyright 2024, The Android Open Source Project
2*5225e6b1SAndroid Build Coastguard Worker //
3*5225e6b1SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*5225e6b1SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*5225e6b1SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*5225e6b1SAndroid Build Coastguard Worker //
7*5225e6b1SAndroid Build Coastguard Worker //     http://www.apache.org/licenses/LICENSE-2.0
8*5225e6b1SAndroid Build Coastguard Worker //
9*5225e6b1SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*5225e6b1SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*5225e6b1SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*5225e6b1SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*5225e6b1SAndroid Build Coastguard Worker // limitations under the License.
14*5225e6b1SAndroid Build Coastguard Worker 
15*5225e6b1SAndroid Build Coastguard Worker //! Unified error type library
16*5225e6b1SAndroid Build Coastguard Worker //!
17*5225e6b1SAndroid Build Coastguard Worker //! This crate defines a common error type for all of GBL.
18*5225e6b1SAndroid Build Coastguard Worker //! It is intended to reduce conversion boilerplate and to make
19*5225e6b1SAndroid Build Coastguard Worker //! the various GBL libraries interoperate more cleanly.
20*5225e6b1SAndroid Build Coastguard Worker //!
21*5225e6b1SAndroid Build Coastguard Worker //! Because of its intended broad application, certain error types will
22*5225e6b1SAndroid Build Coastguard Worker //! be highly specific to particular libraries.
23*5225e6b1SAndroid Build Coastguard Worker //! More specific errors can be useful when writing unit tests or when defining
24*5225e6b1SAndroid Build Coastguard Worker //! APIs that third party code may interact with.
25*5225e6b1SAndroid Build Coastguard Worker //! It's a judgement call whether a new variant should be added,
26*5225e6b1SAndroid Build Coastguard Worker //! but if possible try to use an existing variant.
27*5225e6b1SAndroid Build Coastguard Worker //!
28*5225e6b1SAndroid Build Coastguard Worker //! It is a further judgement call whether a new variant should wrap a payload.
29*5225e6b1SAndroid Build Coastguard Worker //! The rule of thumb is that a payload requires one of the following conditions:
30*5225e6b1SAndroid Build Coastguard Worker //! 1) The error will be logged and the payload will help with debugging.
31*5225e6b1SAndroid Build Coastguard Worker //! 2) The error is transient or retriable, and the payload helps with the retry.
32*5225e6b1SAndroid Build Coastguard Worker //!
33*5225e6b1SAndroid Build Coastguard Worker //! New error variants should be inserted alphabetically.
34*5225e6b1SAndroid Build Coastguard Worker 
35*5225e6b1SAndroid Build Coastguard Worker #![cfg_attr(not(any(test, android_dylib)), no_std)]
36*5225e6b1SAndroid Build Coastguard Worker 
37*5225e6b1SAndroid Build Coastguard Worker use core::{
38*5225e6b1SAndroid Build Coastguard Worker     ffi::{FromBytesUntilNulError, FromBytesWithNulError},
39*5225e6b1SAndroid Build Coastguard Worker     str::Utf8Error,
40*5225e6b1SAndroid Build Coastguard Worker };
41*5225e6b1SAndroid Build Coastguard Worker 
42*5225e6b1SAndroid Build Coastguard Worker use efi_types as efi;
43*5225e6b1SAndroid Build Coastguard Worker 
44*5225e6b1SAndroid Build Coastguard Worker /// Gpt related errors.
45*5225e6b1SAndroid Build Coastguard Worker #[derive(Copy, Clone, Debug, PartialEq, Eq)]
46*5225e6b1SAndroid Build Coastguard Worker pub enum GptError {
47*5225e6b1SAndroid Build Coastguard Worker     /// Secondary header is valid, but different from primary.
48*5225e6b1SAndroid Build Coastguard Worker     DifferentFromPrimary,
49*5225e6b1SAndroid Build Coastguard Worker     /// Disk size is not enough to accommodate maximum allowed entries.
50*5225e6b1SAndroid Build Coastguard Worker     DiskTooSmall,
51*5225e6b1SAndroid Build Coastguard Worker     /// GPT entries buffer is too small for the expected number of entries.
52*5225e6b1SAndroid Build Coastguard Worker     EntriesTruncated,
53*5225e6b1SAndroid Build Coastguard Worker     /// GPT header CRC is not correct.
54*5225e6b1SAndroid Build Coastguard Worker     IncorrectHeaderCrc,
55*5225e6b1SAndroid Build Coastguard Worker     /// GPT header MAGIC is not correct.
56*5225e6b1SAndroid Build Coastguard Worker     IncorrectMagic(u64),
57*5225e6b1SAndroid Build Coastguard Worker     /// GPT entries CRC doesn't match.
58*5225e6b1SAndroid Build Coastguard Worker     IncorrectEntriesCrc,
59*5225e6b1SAndroid Build Coastguard Worker     /// Invalid first and last usable block in the GPT header.
60*5225e6b1SAndroid Build Coastguard Worker     InvalidFirstLastUsableBlock {
61*5225e6b1SAndroid Build Coastguard Worker         /// The value of first usable block in the GPT header.
62*5225e6b1SAndroid Build Coastguard Worker         first: u64,
63*5225e6b1SAndroid Build Coastguard Worker         /// The value of last usable block in the GPT header.
64*5225e6b1SAndroid Build Coastguard Worker         last: u64,
65*5225e6b1SAndroid Build Coastguard Worker         /// Expected range inclusive.
66*5225e6b1SAndroid Build Coastguard Worker         range: (u64, u64),
67*5225e6b1SAndroid Build Coastguard Worker     },
68*5225e6b1SAndroid Build Coastguard Worker     /// Partition range is invalid.
69*5225e6b1SAndroid Build Coastguard Worker     InvalidPartitionRange {
70*5225e6b1SAndroid Build Coastguard Worker         /// Partition index (1-based).
71*5225e6b1SAndroid Build Coastguard Worker         idx: usize,
72*5225e6b1SAndroid Build Coastguard Worker         /// Range of the partition, inclusive.
73*5225e6b1SAndroid Build Coastguard Worker         part_range: (u64, u64),
74*5225e6b1SAndroid Build Coastguard Worker         /// Range of usable block, inclusive.
75*5225e6b1SAndroid Build Coastguard Worker         usable_range: (u64, u64),
76*5225e6b1SAndroid Build Coastguard Worker     },
77*5225e6b1SAndroid Build Coastguard Worker     /// Invalid start block for primary GPT entries.
78*5225e6b1SAndroid Build Coastguard Worker     InvalidPrimaryEntriesStart {
79*5225e6b1SAndroid Build Coastguard Worker         /// The entry start block value.
80*5225e6b1SAndroid Build Coastguard Worker         value: u64,
81*5225e6b1SAndroid Build Coastguard Worker         /// Expected range.
82*5225e6b1SAndroid Build Coastguard Worker         expect_range: (u64, u64),
83*5225e6b1SAndroid Build Coastguard Worker     },
84*5225e6b1SAndroid Build Coastguard Worker     /// Invalid start block for secondary GPT entries.
85*5225e6b1SAndroid Build Coastguard Worker     InvalidSecondaryEntriesStart {
86*5225e6b1SAndroid Build Coastguard Worker         /// The entry start block value.
87*5225e6b1SAndroid Build Coastguard Worker         value: u64,
88*5225e6b1SAndroid Build Coastguard Worker         /// Expected range.
89*5225e6b1SAndroid Build Coastguard Worker         expect_range: (u64, u64),
90*5225e6b1SAndroid Build Coastguard Worker     },
91*5225e6b1SAndroid Build Coastguard Worker     /// Number of entries greater than maximum allowed.
92*5225e6b1SAndroid Build Coastguard Worker     NumberOfEntriesOverflow {
93*5225e6b1SAndroid Build Coastguard Worker         /// Actual number of entries,
94*5225e6b1SAndroid Build Coastguard Worker         entries: u32,
95*5225e6b1SAndroid Build Coastguard Worker         /// Maximum allowed.
96*5225e6b1SAndroid Build Coastguard Worker         max_allowed: usize,
97*5225e6b1SAndroid Build Coastguard Worker     },
98*5225e6b1SAndroid Build Coastguard Worker     /// Two partitions overlap.
99*5225e6b1SAndroid Build Coastguard Worker     PartitionRangeOverlap {
100*5225e6b1SAndroid Build Coastguard Worker         /// Previous partition in overlap. (partition index, first, last)
101*5225e6b1SAndroid Build Coastguard Worker         prev: (usize, u64, u64),
102*5225e6b1SAndroid Build Coastguard Worker         /// Next partition in overlap. (partition index, first, last)
103*5225e6b1SAndroid Build Coastguard Worker         next: (usize, u64, u64),
104*5225e6b1SAndroid Build Coastguard Worker     },
105*5225e6b1SAndroid Build Coastguard Worker     /// Unexpected GPT header size.
106*5225e6b1SAndroid Build Coastguard Worker     UnexpectedEntrySize {
107*5225e6b1SAndroid Build Coastguard Worker         /// The actual entry size in the GPT header.
108*5225e6b1SAndroid Build Coastguard Worker         actual: u32,
109*5225e6b1SAndroid Build Coastguard Worker         /// The expected size.
110*5225e6b1SAndroid Build Coastguard Worker         expect: usize,
111*5225e6b1SAndroid Build Coastguard Worker     },
112*5225e6b1SAndroid Build Coastguard Worker     /// Unexpected GPT header size.
113*5225e6b1SAndroid Build Coastguard Worker     UnexpectedHeaderSize {
114*5225e6b1SAndroid Build Coastguard Worker         /// The actual header size in the GPT header.
115*5225e6b1SAndroid Build Coastguard Worker         actual: u32,
116*5225e6b1SAndroid Build Coastguard Worker         /// The expected size.
117*5225e6b1SAndroid Build Coastguard Worker         expect: usize,
118*5225e6b1SAndroid Build Coastguard Worker     },
119*5225e6b1SAndroid Build Coastguard Worker     /// Zero partition type GUID.
120*5225e6b1SAndroid Build Coastguard Worker     ZeroPartitionTypeGUID {
121*5225e6b1SAndroid Build Coastguard Worker         /// Partition index (1-based).
122*5225e6b1SAndroid Build Coastguard Worker         idx: usize,
123*5225e6b1SAndroid Build Coastguard Worker     },
124*5225e6b1SAndroid Build Coastguard Worker     /// Zero partition unique GUID.
125*5225e6b1SAndroid Build Coastguard Worker     ZeroPartitionUniqueGUID {
126*5225e6b1SAndroid Build Coastguard Worker         /// Partition index (1-based).
127*5225e6b1SAndroid Build Coastguard Worker         idx: usize,
128*5225e6b1SAndroid Build Coastguard Worker     },
129*5225e6b1SAndroid Build Coastguard Worker }
130*5225e6b1SAndroid Build Coastguard Worker 
131*5225e6b1SAndroid Build Coastguard Worker /// Common, universal error type
132*5225e6b1SAndroid Build Coastguard Worker #[derive(Copy, Clone, Debug, PartialEq, Eq)]
133*5225e6b1SAndroid Build Coastguard Worker pub enum Error {
134*5225e6b1SAndroid Build Coastguard Worker     /// An operation has been aborted. Useful for async or IO operations.
135*5225e6b1SAndroid Build Coastguard Worker     Aborted,
136*5225e6b1SAndroid Build Coastguard Worker     /// Access was denied.
137*5225e6b1SAndroid Build Coastguard Worker     AccessDenied,
138*5225e6b1SAndroid Build Coastguard Worker     /// The protocol has already been started.
139*5225e6b1SAndroid Build Coastguard Worker     AlreadyStarted,
140*5225e6b1SAndroid Build Coastguard Worker     /// A checked arithmetic operation has overflowed.
141*5225e6b1SAndroid Build Coastguard Worker     ArithmeticOverflow(safemath::Error),
142*5225e6b1SAndroid Build Coastguard Worker     /// The buffer was not the proper size for the request (different from BufferTooSmall).
143*5225e6b1SAndroid Build Coastguard Worker     BadBufferSize,
144*5225e6b1SAndroid Build Coastguard Worker     /// Data verification has encountered an invalid checksum.
145*5225e6b1SAndroid Build Coastguard Worker     BadChecksum,
146*5225e6b1SAndroid Build Coastguard Worker     /// An operation attempted to access data outside of the valid range.
147*5225e6b1SAndroid Build Coastguard Worker     /// Includes the problematic index.
148*5225e6b1SAndroid Build Coastguard Worker     BadIndex(usize),
149*5225e6b1SAndroid Build Coastguard Worker     /// Data verification has encountered an invalid magic number.
150*5225e6b1SAndroid Build Coastguard Worker     BadMagic,
151*5225e6b1SAndroid Build Coastguard Worker     /// Generic BlockIO error.
152*5225e6b1SAndroid Build Coastguard Worker     BlockIoError,
153*5225e6b1SAndroid Build Coastguard Worker     /// Generic boot failure has occurred.
154*5225e6b1SAndroid Build Coastguard Worker     BootFailed,
155*5225e6b1SAndroid Build Coastguard Worker     /// Buffers provided by third party code overlap.
156*5225e6b1SAndroid Build Coastguard Worker     BufferOverlap,
157*5225e6b1SAndroid Build Coastguard Worker     /// The provided buffer is too small.
158*5225e6b1SAndroid Build Coastguard Worker     /// If Some(n), provides the minimum required buffer size.
159*5225e6b1SAndroid Build Coastguard Worker     BufferTooSmall(Option<usize>),
160*5225e6b1SAndroid Build Coastguard Worker     /// The security status of the data is unknown or compromised
161*5225e6b1SAndroid Build Coastguard Worker     /// and the data must be updated or replaced to restore a valid security status.
162*5225e6b1SAndroid Build Coastguard Worker     CompromisedData,
163*5225e6b1SAndroid Build Coastguard Worker     /// The remote peer has reset the network connection.
164*5225e6b1SAndroid Build Coastguard Worker     ConnectionReset,
165*5225e6b1SAndroid Build Coastguard Worker     /// A relevant device encountered an error.
166*5225e6b1SAndroid Build Coastguard Worker     DeviceError,
167*5225e6b1SAndroid Build Coastguard Worker     /// The connected peripheral or network peer has disconnected.
168*5225e6b1SAndroid Build Coastguard Worker     Disconnected,
169*5225e6b1SAndroid Build Coastguard Worker     /// The end of the file was reached.
170*5225e6b1SAndroid Build Coastguard Worker     EndOfFile,
171*5225e6b1SAndroid Build Coastguard Worker     /// Beginning or end of media was reached
172*5225e6b1SAndroid Build Coastguard Worker     EndOfMedia,
173*5225e6b1SAndroid Build Coastguard Worker     /// A polled operation has finished
174*5225e6b1SAndroid Build Coastguard Worker     Finished,
175*5225e6b1SAndroid Build Coastguard Worker     /// GPT related errors.
176*5225e6b1SAndroid Build Coastguard Worker     GptError(GptError),
177*5225e6b1SAndroid Build Coastguard Worker     /// A HTTP error occurred during a network operation.
178*5225e6b1SAndroid Build Coastguard Worker     HttpError,
179*5225e6b1SAndroid Build Coastguard Worker     /// An ICMP error occurred during a network operation.
180*5225e6b1SAndroid Build Coastguard Worker     IcmpError,
181*5225e6b1SAndroid Build Coastguard Worker     /// The provided buffer or data structure is invalidly aligned.
182*5225e6b1SAndroid Build Coastguard Worker     InvalidAlignment,
183*5225e6b1SAndroid Build Coastguard Worker     /// A connected agent failed a multi-stage handshake.
184*5225e6b1SAndroid Build Coastguard Worker     InvalidHandshake,
185*5225e6b1SAndroid Build Coastguard Worker     /// At least one parameter fails preconditions.
186*5225e6b1SAndroid Build Coastguard Worker     InvalidInput,
187*5225e6b1SAndroid Build Coastguard Worker     /// The language specified was invalid.
188*5225e6b1SAndroid Build Coastguard Worker     InvalidLanguage,
189*5225e6b1SAndroid Build Coastguard Worker     /// A state machine has entered an invalid state.
190*5225e6b1SAndroid Build Coastguard Worker     InvalidState,
191*5225e6b1SAndroid Build Coastguard Worker     /// There was a conflict in IP address allocation.
192*5225e6b1SAndroid Build Coastguard Worker     IpAddressConflict,
193*5225e6b1SAndroid Build Coastguard Worker     /// Image failed to load
194*5225e6b1SAndroid Build Coastguard Worker     LoadError,
195*5225e6b1SAndroid Build Coastguard Worker     /// The medium in the device has changed since the last access.
196*5225e6b1SAndroid Build Coastguard Worker     MediaChanged,
197*5225e6b1SAndroid Build Coastguard Worker     /// Memory map error with error code.
198*5225e6b1SAndroid Build Coastguard Worker     MemoryMapCallbackError(i64),
199*5225e6b1SAndroid Build Coastguard Worker     /// An image required for system boot is missing.
200*5225e6b1SAndroid Build Coastguard Worker     MissingImage,
201*5225e6b1SAndroid Build Coastguard Worker     /// A valid Flattened Device Tree was not found.
202*5225e6b1SAndroid Build Coastguard Worker     NoFdt,
203*5225e6b1SAndroid Build Coastguard Worker     /// The block device does not have a valid GUID Partition Table.
204*5225e6b1SAndroid Build Coastguard Worker     NoGpt,
205*5225e6b1SAndroid Build Coastguard Worker     /// A mapping to a device does not exist.
206*5225e6b1SAndroid Build Coastguard Worker     NoMapping,
207*5225e6b1SAndroid Build Coastguard Worker     /// The device does not contain any medium to perform the operation.
208*5225e6b1SAndroid Build Coastguard Worker     NoMedia,
209*5225e6b1SAndroid Build Coastguard Worker     /// The server was not found or did not respond to the request.
210*5225e6b1SAndroid Build Coastguard Worker     NoResponse,
211*5225e6b1SAndroid Build Coastguard Worker     /// The requested element (e.g. device, partition, or value) was not found.
212*5225e6b1SAndroid Build Coastguard Worker     NotFound,
213*5225e6b1SAndroid Build Coastguard Worker     /// The default implementation for a trait method has not been overridden.
214*5225e6b1SAndroid Build Coastguard Worker     NotImplemented,
215*5225e6b1SAndroid Build Coastguard Worker     /// The polled device or future is not ready.
216*5225e6b1SAndroid Build Coastguard Worker     NotReady,
217*5225e6b1SAndroid Build Coastguard Worker     /// The protocol has not been started.
218*5225e6b1SAndroid Build Coastguard Worker     NotStarted,
219*5225e6b1SAndroid Build Coastguard Worker     /// The provided name does not uniquely describe a partition.
220*5225e6b1SAndroid Build Coastguard Worker     NotUnique,
221*5225e6b1SAndroid Build Coastguard Worker     /// Generic permissions failure.
222*5225e6b1SAndroid Build Coastguard Worker     OperationProhibited,
223*5225e6b1SAndroid Build Coastguard Worker     /// Catch-all error with optional debugging string.
224*5225e6b1SAndroid Build Coastguard Worker     Other(Option<&'static str>),
225*5225e6b1SAndroid Build Coastguard Worker     /// A resource has run out.
226*5225e6b1SAndroid Build Coastguard Worker     OutOfResources,
227*5225e6b1SAndroid Build Coastguard Worker     /// A protocol error occurred during the network operation.
228*5225e6b1SAndroid Build Coastguard Worker     ProtocolError,
229*5225e6b1SAndroid Build Coastguard Worker     /// The function was not performed due to a security violation.
230*5225e6b1SAndroid Build Coastguard Worker     SecurityViolation,
231*5225e6b1SAndroid Build Coastguard Worker     /// A TFTP error occurred during a network operation.
232*5225e6b1SAndroid Build Coastguard Worker     TftpError,
233*5225e6b1SAndroid Build Coastguard Worker     /// Operation has timed out.
234*5225e6b1SAndroid Build Coastguard Worker     Timeout,
235*5225e6b1SAndroid Build Coastguard Worker     /// The remote network endpoint is not addressable.
236*5225e6b1SAndroid Build Coastguard Worker     Unaddressable,
237*5225e6b1SAndroid Build Coastguard Worker     /// An unknown, unexpected EFI_STATUS error code was returned,
238*5225e6b1SAndroid Build Coastguard Worker     UnexpectedEfiError(efi::EfiStatus),
239*5225e6b1SAndroid Build Coastguard Worker     /// Operation is unsupported
240*5225e6b1SAndroid Build Coastguard Worker     Unsupported,
241*5225e6b1SAndroid Build Coastguard Worker     /// Data verification has encountered a version number that is not supported.
242*5225e6b1SAndroid Build Coastguard Worker     UnsupportedVersion,
243*5225e6b1SAndroid Build Coastguard Worker     /// An inconstancy was detected on the file system causing the operating to fail.
244*5225e6b1SAndroid Build Coastguard Worker     VolumeCorrupted,
245*5225e6b1SAndroid Build Coastguard Worker     /// There is no more space on the file system.
246*5225e6b1SAndroid Build Coastguard Worker     VolumeFull,
247*5225e6b1SAndroid Build Coastguard Worker     /// The device cannot be written to.
248*5225e6b1SAndroid Build Coastguard Worker     WriteProtected,
249*5225e6b1SAndroid Build Coastguard Worker }
250*5225e6b1SAndroid Build Coastguard Worker 
251*5225e6b1SAndroid Build Coastguard Worker impl From<Option<&'static str>> for Error {
from(val: Option<&'static str>) -> Self252*5225e6b1SAndroid Build Coastguard Worker     fn from(val: Option<&'static str>) -> Self {
253*5225e6b1SAndroid Build Coastguard Worker         Self::Other(val)
254*5225e6b1SAndroid Build Coastguard Worker     }
255*5225e6b1SAndroid Build Coastguard Worker }
256*5225e6b1SAndroid Build Coastguard Worker 
257*5225e6b1SAndroid Build Coastguard Worker impl From<&'static str> for Error {
from(val: &'static str) -> Self258*5225e6b1SAndroid Build Coastguard Worker     fn from(val: &'static str) -> Self {
259*5225e6b1SAndroid Build Coastguard Worker         Self::Other(Some(val))
260*5225e6b1SAndroid Build Coastguard Worker     }
261*5225e6b1SAndroid Build Coastguard Worker }
262*5225e6b1SAndroid Build Coastguard Worker 
263*5225e6b1SAndroid Build Coastguard Worker impl From<safemath::Error> for Error {
from(err: safemath::Error) -> Self264*5225e6b1SAndroid Build Coastguard Worker     fn from(err: safemath::Error) -> Self {
265*5225e6b1SAndroid Build Coastguard Worker         Self::ArithmeticOverflow(err)
266*5225e6b1SAndroid Build Coastguard Worker     }
267*5225e6b1SAndroid Build Coastguard Worker }
268*5225e6b1SAndroid Build Coastguard Worker 
269*5225e6b1SAndroid Build Coastguard Worker impl From<core::num::TryFromIntError> for Error {
270*5225e6b1SAndroid Build Coastguard Worker     #[track_caller]
from(err: core::num::TryFromIntError) -> Self271*5225e6b1SAndroid Build Coastguard Worker     fn from(err: core::num::TryFromIntError) -> Self {
272*5225e6b1SAndroid Build Coastguard Worker         Self::ArithmeticOverflow(err.into())
273*5225e6b1SAndroid Build Coastguard Worker     }
274*5225e6b1SAndroid Build Coastguard Worker }
275*5225e6b1SAndroid Build Coastguard Worker 
276*5225e6b1SAndroid Build Coastguard Worker impl From<FromBytesUntilNulError> for Error {
from(_: FromBytesUntilNulError) -> Self277*5225e6b1SAndroid Build Coastguard Worker     fn from(_: FromBytesUntilNulError) -> Self {
278*5225e6b1SAndroid Build Coastguard Worker         Self::InvalidInput
279*5225e6b1SAndroid Build Coastguard Worker     }
280*5225e6b1SAndroid Build Coastguard Worker }
281*5225e6b1SAndroid Build Coastguard Worker 
282*5225e6b1SAndroid Build Coastguard Worker impl From<FromBytesWithNulError> for Error {
from(_: FromBytesWithNulError) -> Self283*5225e6b1SAndroid Build Coastguard Worker     fn from(_: FromBytesWithNulError) -> Self {
284*5225e6b1SAndroid Build Coastguard Worker         Self::InvalidInput
285*5225e6b1SAndroid Build Coastguard Worker     }
286*5225e6b1SAndroid Build Coastguard Worker }
287*5225e6b1SAndroid Build Coastguard Worker 
288*5225e6b1SAndroid Build Coastguard Worker impl From<Utf8Error> for Error {
from(_: Utf8Error) -> Self289*5225e6b1SAndroid Build Coastguard Worker     fn from(_: Utf8Error) -> Self {
290*5225e6b1SAndroid Build Coastguard Worker         Self::InvalidInput
291*5225e6b1SAndroid Build Coastguard Worker     }
292*5225e6b1SAndroid Build Coastguard Worker }
293*5225e6b1SAndroid Build Coastguard Worker 
294*5225e6b1SAndroid Build Coastguard Worker impl core::fmt::Display for Error {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result295*5225e6b1SAndroid Build Coastguard Worker     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
296*5225e6b1SAndroid Build Coastguard Worker         write!(f, "{:#?}", self)
297*5225e6b1SAndroid Build Coastguard Worker     }
298*5225e6b1SAndroid Build Coastguard Worker }
299*5225e6b1SAndroid Build Coastguard Worker 
300*5225e6b1SAndroid Build Coastguard Worker impl From<core::fmt::Error> for Error {
from(_: core::fmt::Error) -> Self301*5225e6b1SAndroid Build Coastguard Worker     fn from(_: core::fmt::Error) -> Self {
302*5225e6b1SAndroid Build Coastguard Worker         Self::Unsupported
303*5225e6b1SAndroid Build Coastguard Worker     }
304*5225e6b1SAndroid Build Coastguard Worker }
305*5225e6b1SAndroid Build Coastguard Worker 
306*5225e6b1SAndroid Build Coastguard Worker /// Helper type alias.
307*5225e6b1SAndroid Build Coastguard Worker pub type Result<T> = core::result::Result<T, Error>;
308*5225e6b1SAndroid Build Coastguard Worker 
309*5225e6b1SAndroid Build Coastguard Worker /// Workaround for orphan rule.
efi_status_to_result(e: efi::EfiStatus) -> Result<()>310*5225e6b1SAndroid Build Coastguard Worker pub fn efi_status_to_result(e: efi::EfiStatus) -> Result<()> {
311*5225e6b1SAndroid Build Coastguard Worker     match e {
312*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_SUCCESS => Ok(()),
313*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_CRC_ERROR => Err(Error::BadChecksum),
314*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_ABORTED => Err(Error::Aborted),
315*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_ACCESS_DENIED => Err(Error::AccessDenied),
316*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_ALREADY_STARTED => Err(Error::AlreadyStarted),
317*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_BAD_BUFFER_SIZE => Err(Error::BadBufferSize),
318*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_BUFFER_TOO_SMALL => Err(Error::BufferTooSmall(None)),
319*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_COMPROMISED_DATA => Err(Error::CompromisedData),
320*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_CONNECTION_FIN => Err(Error::Disconnected),
321*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_CONNECTION_REFUSED => Err(Error::OperationProhibited),
322*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_CONNECTION_RESET => Err(Error::ConnectionReset),
323*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_DEVICE_ERROR => Err(Error::DeviceError),
324*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_END_OF_FILE => Err(Error::EndOfFile),
325*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_END_OF_MEDIA => Err(Error::EndOfMedia),
326*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_HTTP_ERROR => Err(Error::HttpError),
327*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_ICMP_ERROR => Err(Error::IcmpError),
328*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_INCOMPATIBLE_VERSION => Err(Error::UnsupportedVersion),
329*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_INVALID_LANGUAGE => Err(Error::InvalidLanguage),
330*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_INVALID_PARAMETER => Err(Error::InvalidInput),
331*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_IP_ADDRESS_CONFLICT => Err(Error::IpAddressConflict),
332*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_LOAD_ERROR => Err(Error::LoadError),
333*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_MEDIA_CHANGED => Err(Error::MediaChanged),
334*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_NOT_FOUND => Err(Error::NotFound),
335*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_NOT_READY => Err(Error::NotReady),
336*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_NOT_STARTED => Err(Error::NotStarted),
337*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_NO_MAPPING => Err(Error::NoMapping),
338*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_NO_MEDIA => Err(Error::NoMedia),
339*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_NO_RESPONSE => Err(Error::NoResponse),
340*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_OUT_OF_RESOURCES => Err(Error::OutOfResources),
341*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_PROTOCOL_ERROR => Err(Error::ProtocolError),
342*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_SECURITY_VIOLATION => Err(Error::SecurityViolation),
343*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_TFTP_ERROR => Err(Error::TftpError),
344*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_TIMEOUT => Err(Error::Timeout),
345*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_UNSUPPORTED => Err(Error::Unsupported),
346*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_VOLUME_CORRUPTED => Err(Error::VolumeCorrupted),
347*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_VOLUME_FULL => Err(Error::VolumeFull),
348*5225e6b1SAndroid Build Coastguard Worker         efi::EFI_STATUS_WRITE_PROTECTED => Err(Error::WriteProtected),
349*5225e6b1SAndroid Build Coastguard Worker         // The UEFI spec reserves part of the error space for
350*5225e6b1SAndroid Build Coastguard Worker         // OEM defined errors and warnings.
351*5225e6b1SAndroid Build Coastguard Worker         // We can't know in advance what these are or what they mean,
352*5225e6b1SAndroid Build Coastguard Worker         // so just preserve them as is.
353*5225e6b1SAndroid Build Coastguard Worker         e => Err(Error::UnexpectedEfiError(e)),
354*5225e6b1SAndroid Build Coastguard Worker     }
355*5225e6b1SAndroid Build Coastguard Worker }
356*5225e6b1SAndroid Build Coastguard Worker 
357*5225e6b1SAndroid Build Coastguard Worker #[cfg(test)]
358*5225e6b1SAndroid Build Coastguard Worker mod test {
359*5225e6b1SAndroid Build Coastguard Worker     use super::*;
360*5225e6b1SAndroid Build Coastguard Worker 
361*5225e6b1SAndroid Build Coastguard Worker     #[test]
test_from_safemath_error()362*5225e6b1SAndroid Build Coastguard Worker     fn test_from_safemath_error() {
363*5225e6b1SAndroid Build Coastguard Worker         let n = u8::try_from(safemath::SafeNum::ZERO - 1).unwrap_err();
364*5225e6b1SAndroid Build Coastguard Worker         let _e: Error = n.into();
365*5225e6b1SAndroid Build Coastguard Worker     }
366*5225e6b1SAndroid Build Coastguard Worker 
367*5225e6b1SAndroid Build Coastguard Worker     #[test]
test_from_str()368*5225e6b1SAndroid Build Coastguard Worker     fn test_from_str() {
369*5225e6b1SAndroid Build Coastguard Worker         let _e: Error = "error string".into();
370*5225e6b1SAndroid Build Coastguard Worker     }
371*5225e6b1SAndroid Build Coastguard Worker 
372*5225e6b1SAndroid Build Coastguard Worker     #[test]
test_from_str_option()373*5225e6b1SAndroid Build Coastguard Worker     fn test_from_str_option() {
374*5225e6b1SAndroid Build Coastguard Worker         let _e: Error = Some("error string").into();
375*5225e6b1SAndroid Build Coastguard Worker         let n: Option<&str> = None;
376*5225e6b1SAndroid Build Coastguard Worker         let _e2: Error = n.into();
377*5225e6b1SAndroid Build Coastguard Worker     }
378*5225e6b1SAndroid Build Coastguard Worker }
379