xref: /aosp_15_r20/bootable/libbootloader/gbl/libgbl/src/error.rs (revision 5225e6b173e52d2efc6bcf950c27374fd72adabc)
1*5225e6b1SAndroid Build Coastguard Worker // Copyright 2023, 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 //! Error types used in libgbl.
16*5225e6b1SAndroid Build Coastguard Worker 
17*5225e6b1SAndroid Build Coastguard Worker use avb::{DescriptorError, IoError, SlotVerifyError};
18*5225e6b1SAndroid Build Coastguard Worker use core::fmt::{Debug, Display, Formatter};
19*5225e6b1SAndroid Build Coastguard Worker 
20*5225e6b1SAndroid Build Coastguard Worker /// A helper macro for declaring a composite enum type that simply wraps other types as entries.
21*5225e6b1SAndroid Build Coastguard Worker /// It auto-generate `From<...>` implementation for each entry type. The type for each entry must
22*5225e6b1SAndroid Build Coastguard Worker /// be different from each other. i.e.:
23*5225e6b1SAndroid Build Coastguard Worker ///
24*5225e6b1SAndroid Build Coastguard Worker /// ```rust
25*5225e6b1SAndroid Build Coastguard Worker ///   composite_enum! {
26*5225e6b1SAndroid Build Coastguard Worker ///       pub enum MyEnum {
27*5225e6b1SAndroid Build Coastguard Worker ///           Usize(usize),
28*5225e6b1SAndroid Build Coastguard Worker ///           I64(i64),
29*5225e6b1SAndroid Build Coastguard Worker ///       }
30*5225e6b1SAndroid Build Coastguard Worker ///   }
31*5225e6b1SAndroid Build Coastguard Worker /// ```
32*5225e6b1SAndroid Build Coastguard Worker ///
33*5225e6b1SAndroid Build Coastguard Worker /// expands to
34*5225e6b1SAndroid Build Coastguard Worker ///
35*5225e6b1SAndroid Build Coastguard Worker /// ```rust
36*5225e6b1SAndroid Build Coastguard Worker ///   pub enum MyEnum {
37*5225e6b1SAndroid Build Coastguard Worker ///       Usize(usize),
38*5225e6b1SAndroid Build Coastguard Worker ///       I64(i64),
39*5225e6b1SAndroid Build Coastguard Worker ///   }
40*5225e6b1SAndroid Build Coastguard Worker ///
41*5225e6b1SAndroid Build Coastguard Worker ///   impl From<usize> for MyEnum {
42*5225e6b1SAndroid Build Coastguard Worker ///       fn from(ent: usize) -> MyEnum {
43*5225e6b1SAndroid Build Coastguard Worker ///           MyEnum::Usize(ent)
44*5225e6b1SAndroid Build Coastguard Worker ///       }
45*5225e6b1SAndroid Build Coastguard Worker ///   }
46*5225e6b1SAndroid Build Coastguard Worker ///
47*5225e6b1SAndroid Build Coastguard Worker ///   impl From<i64> for MyEnum {
48*5225e6b1SAndroid Build Coastguard Worker ///       fn from(ent: i64) -> MyEnum {
49*5225e6b1SAndroid Build Coastguard Worker ///           MyEnum::I64(ent)
50*5225e6b1SAndroid Build Coastguard Worker ///       }
51*5225e6b1SAndroid Build Coastguard Worker ///   }
52*5225e6b1SAndroid Build Coastguard Worker /// ```
53*5225e6b1SAndroid Build Coastguard Worker #[macro_export]
54*5225e6b1SAndroid Build Coastguard Worker macro_rules! composite_enum {
55*5225e6b1SAndroid Build Coastguard Worker     (
56*5225e6b1SAndroid Build Coastguard Worker         $(#[$outer:meta])*
57*5225e6b1SAndroid Build Coastguard Worker         $vis:vis enum $name:ident {
58*5225e6b1SAndroid Build Coastguard Worker             $(
59*5225e6b1SAndroid Build Coastguard Worker                 $(#[$inner:ident $($args:tt)*])*
60*5225e6b1SAndroid Build Coastguard Worker                 $ent:ident($ent_t:ty)
61*5225e6b1SAndroid Build Coastguard Worker             ),*
62*5225e6b1SAndroid Build Coastguard Worker             $(,)*
63*5225e6b1SAndroid Build Coastguard Worker         }
64*5225e6b1SAndroid Build Coastguard Worker     ) => {
65*5225e6b1SAndroid Build Coastguard Worker         #[allow(missing_docs)]
66*5225e6b1SAndroid Build Coastguard Worker         // Copy over enum declaration as it is.
67*5225e6b1SAndroid Build Coastguard Worker         $(#[$outer])*
68*5225e6b1SAndroid Build Coastguard Worker         $vis enum $name {
69*5225e6b1SAndroid Build Coastguard Worker             $(
70*5225e6b1SAndroid Build Coastguard Worker                 $(#[$inner $($args)*])*
71*5225e6b1SAndroid Build Coastguard Worker                 $ent($ent_t)
72*5225e6b1SAndroid Build Coastguard Worker             ),*
73*5225e6b1SAndroid Build Coastguard Worker         }
74*5225e6b1SAndroid Build Coastguard Worker 
75*5225e6b1SAndroid Build Coastguard Worker         // Generate `From<...>` implementation.
76*5225e6b1SAndroid Build Coastguard Worker         composite_enum!{$name,  $($ent($ent_t)),*}
77*5225e6b1SAndroid Build Coastguard Worker     };
78*5225e6b1SAndroid Build Coastguard Worker     // `From<>` implementation generation. Base case.
79*5225e6b1SAndroid Build Coastguard Worker     ($name:ident, $ent:ident($ent_t:ty)) => {
80*5225e6b1SAndroid Build Coastguard Worker         impl From<$ent_t> for $name {
81*5225e6b1SAndroid Build Coastguard Worker             fn from(ent: $ent_t) -> $name {
82*5225e6b1SAndroid Build Coastguard Worker                 $name::$ent(ent)
83*5225e6b1SAndroid Build Coastguard Worker             }
84*5225e6b1SAndroid Build Coastguard Worker         }
85*5225e6b1SAndroid Build Coastguard Worker     };
86*5225e6b1SAndroid Build Coastguard Worker     // `From<>` implementation generation. Recursive case.
87*5225e6b1SAndroid Build Coastguard Worker     ($name:ident, $ent:ident($ent_t:ty), $($next:ident($next_t:ty)),+) => {
88*5225e6b1SAndroid Build Coastguard Worker         composite_enum!{$name, $ent($ent_t)}
89*5225e6b1SAndroid Build Coastguard Worker         composite_enum!{$name, $($next($next_t)),*}
90*5225e6b1SAndroid Build Coastguard Worker     };
91*5225e6b1SAndroid Build Coastguard Worker }
92*5225e6b1SAndroid Build Coastguard Worker 
93*5225e6b1SAndroid Build Coastguard Worker composite_enum! {
94*5225e6b1SAndroid Build Coastguard Worker     /// Top level error type that integrates errors from various dependency libraries.
95*5225e6b1SAndroid Build Coastguard Worker     #[derive(Debug, PartialEq, Eq)]
96*5225e6b1SAndroid Build Coastguard Worker     pub enum IntegrationError {
97*5225e6b1SAndroid Build Coastguard Worker         /// Failed to get descriptor from AvbMeta
98*5225e6b1SAndroid Build Coastguard Worker         AvbDescriptorError(DescriptorError),
99*5225e6b1SAndroid Build Coastguard Worker         AvbIoError(IoError),
100*5225e6b1SAndroid Build Coastguard Worker         /// Avb slot verification failed.
101*5225e6b1SAndroid Build Coastguard Worker         /// SlotVerifyError is used without verify data.
102*5225e6b1SAndroid Build Coastguard Worker         AvbSlotVerifyError(SlotVerifyError<'static>),
103*5225e6b1SAndroid Build Coastguard Worker         UnificationError(liberror::Error),
104*5225e6b1SAndroid Build Coastguard Worker         ZbiError(zbi::ZbiError),
105*5225e6b1SAndroid Build Coastguard Worker     }
106*5225e6b1SAndroid Build Coastguard Worker }
107*5225e6b1SAndroid Build Coastguard Worker 
108*5225e6b1SAndroid Build Coastguard Worker impl Display for IntegrationError {
fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result109*5225e6b1SAndroid Build Coastguard Worker     fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
110*5225e6b1SAndroid Build Coastguard Worker         write!(f, "{:?}", self)
111*5225e6b1SAndroid Build Coastguard Worker     }
112*5225e6b1SAndroid Build Coastguard Worker }
113*5225e6b1SAndroid Build Coastguard Worker 
114*5225e6b1SAndroid Build Coastguard Worker /// Helper type GBL functions will return.
115*5225e6b1SAndroid Build Coastguard Worker pub type Result<T> = core::result::Result<T, IntegrationError>;
116