@@ -31,11 +31,14 @@ pub mod time;
31
31
32
32
mod status;
33
33
34
- use core:: ffi:: c_void;
35
- use core:: fmt:: { self , Debug , Formatter } ;
36
34
pub use status:: Status ;
37
35
pub use uguid:: { guid, Guid } ;
38
36
37
+ #[ cfg( feature = "unstable" ) ]
38
+ use core:: error:: Error ;
39
+ use core:: ffi:: c_void;
40
+ use core:: fmt:: { self , Debug , Display , Formatter } ;
41
+
39
42
/// Handle to an event structure.
40
43
pub type Event = * mut c_void ;
41
44
@@ -65,6 +68,58 @@ pub type PhysicalAddress = u64;
65
68
/// of target platform.
66
69
pub type VirtualAddress = u64 ;
67
70
71
+ /// The provided [`Boolean`] can't be converted to [`bool`] as it is neither
72
+ /// `0` nor `1`.
73
+ #[ derive( Debug , Copy , Clone , PartialEq , Ord , PartialOrd , Eq ) ]
74
+ pub struct InvalidBooleanError ( u8 ) ;
75
+
76
+ impl Display for InvalidBooleanError {
77
+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> fmt:: Result {
78
+ Debug :: fmt ( self , f)
79
+ }
80
+ }
81
+
82
+ #[ cfg( feature = "unstable" ) ]
83
+ impl Error for InvalidBooleanError { }
84
+
85
+ /// ABI-compatible UEFI boolean.
86
+ ///
87
+ /// Opaque 1-byte value holding either `0` for FALSE or a `1` for TRUE. This
88
+ /// type can be converted from and to `bool` via corresponding [`From`]
89
+ /// respectively [`TryFrom`] implementations.
90
+ #[ derive( Copy , Clone , Debug , Default , PartialEq , Ord , PartialOrd , Eq , Hash ) ]
91
+ #[ repr( transparent) ]
92
+ pub struct Boolean ( u8 ) ;
93
+
94
+ impl Boolean {
95
+ /// [`Boolean`] representing `true`.
96
+ pub const TRUE : Self = Self ( 1 ) ;
97
+
98
+ /// [`Boolean`] representing `false`.
99
+ pub const FALSE : Self = Self ( 0 ) ;
100
+ }
101
+
102
+ impl From < bool > for Boolean {
103
+ fn from ( value : bool ) -> Self {
104
+ match value {
105
+ true => Self ( 1 ) ,
106
+ false => Self ( 0 ) ,
107
+ }
108
+ }
109
+ }
110
+
111
+ impl TryFrom < Boolean > for bool {
112
+ type Error = InvalidBooleanError ;
113
+
114
+ fn try_from ( value : Boolean ) -> Result < Self , Self :: Error > {
115
+ match value. 0 {
116
+ 0 => Ok ( false ) ,
117
+ 1 => Ok ( true ) ,
118
+ x => Err ( InvalidBooleanError ( x) ) ,
119
+ }
120
+ }
121
+ }
122
+
68
123
/// An IPv4 internet protocol address.
69
124
#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
70
125
#[ repr( transparent) ]
@@ -133,3 +188,31 @@ impl Default for IpAddress {
133
188
#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
134
189
#[ repr( transparent) ]
135
190
pub struct MacAddress ( pub [ u8 ; 32 ] ) ;
191
+
192
+ #[ cfg( test) ]
193
+ mod tests {
194
+ use super :: * ;
195
+
196
+ #[ test]
197
+ /// Test the properties promised in [0]. This also applies for the other
198
+ /// architectures.
199
+ ///
200
+ /// [0] https://github.com/tianocore/edk2/blob/b0f43dd3fdec2363e3548ec31eb455dc1c4ac761/MdePkg/Include/X64/ProcessorBind.h#L192
201
+ fn test_boolean_abi ( ) {
202
+ assert_eq ! ( size_of:: <Boolean >( ) , 1 ) ;
203
+ assert_eq ! ( Boolean :: from( true ) . 0 , 1 ) ;
204
+ assert_eq ! ( Boolean :: from( false ) . 0 , 0 ) ;
205
+ assert_eq ! ( Boolean :: TRUE . 0 , 1 ) ;
206
+ assert_eq ! ( Boolean :: FALSE . 0 , 0 ) ;
207
+ assert_eq ! ( bool :: try_from( Boolean ( 0b0 ) ) , Ok ( false ) ) ;
208
+ assert_eq ! ( bool :: try_from( Boolean ( 0b1 ) ) , Ok ( true ) ) ;
209
+ assert_eq ! (
210
+ bool :: try_from( Boolean ( 0b11 ) ) ,
211
+ Err ( InvalidBooleanError ( 0b11 ) )
212
+ ) ;
213
+ assert_eq ! (
214
+ bool :: try_from( Boolean ( 0b10 ) ) ,
215
+ Err ( InvalidBooleanError ( 0b10 ) )
216
+ ) ;
217
+ }
218
+ }
0 commit comments