@@ -31,11 +31,14 @@ pub mod time;
3131
3232mod status;
3333
34- use core:: ffi:: c_void;
35- use core:: fmt:: { self , Debug , Formatter } ;
3634pub use status:: Status ;
3735pub use uguid:: { guid, Guid } ;
3836
37+ #[ cfg( feature = "unstable" ) ]
38+ use core:: error:: Error ;
39+ use core:: ffi:: c_void;
40+ use core:: fmt:: { self , Debug , Display , Formatter } ;
41+
3942/// Handle to an event structure.
4043pub type Event = * mut c_void ;
4144
@@ -65,6 +68,58 @@ pub type PhysicalAddress = u64;
6568/// of target platform.
6669pub type VirtualAddress = u64 ;
6770
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+
68123/// An IPv4 internet protocol address.
69124#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
70125#[ repr( transparent) ]
@@ -133,3 +188,31 @@ impl Default for IpAddress {
133188#[ derive( Clone , Copy , Debug , Default , Eq , PartialEq , Ord , PartialOrd , Hash ) ]
134189#[ repr( transparent) ]
135190pub 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