@@ -12,20 +12,29 @@ use core::fmt;
1212#[ cfg( not( target_env = "sgx" ) ) ]
1313use std:: { io, error} ;
1414
15+ // A randomly-chosen 16-bit prefix for our codes
16+ pub ( crate ) const CODE_PREFIX : u32 = 0x57f40000 ;
17+ const CODE_UNKNOWN : u32 = CODE_PREFIX | 0 ;
18+ const CODE_UNAVAILABLE : u32 = CODE_PREFIX | 1 ;
19+
1520/// An unknown error.
16- pub const UNKNOWN_ERROR : Error = Error ( unsafe {
17- NonZeroU32 :: new_unchecked ( 0x756e6b6e ) // "unkn"
21+ ///
22+ /// This is the following constant: 57F40000 (hex) / 1475608576 (decimal).
23+ pub const ERROR_UNKNOWN : Error = Error ( unsafe {
24+ NonZeroU32 :: new_unchecked ( CODE_UNKNOWN )
1825} ) ;
1926
2027/// No generator is available.
21- pub const UNAVAILABLE_ERROR : Error = Error ( unsafe {
22- NonZeroU32 :: new_unchecked ( 0x4e416e61 ) // "NAna"
28+ ///
29+ /// This is the following constant: 57F40001 (hex) / 1475608577 (decimal).
30+ pub const ERROR_UNAVAILABLE : Error = Error ( unsafe {
31+ NonZeroU32 :: new_unchecked ( CODE_UNAVAILABLE )
2332} ) ;
2433
2534/// The error type.
2635///
2736/// This type is small and no-std compatible.
28- #[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
37+ #[ derive( Copy , Clone , Eq , PartialEq ) ]
2938pub struct Error ( NonZeroU32 ) ;
3039
3140impl Error {
@@ -38,14 +47,34 @@ impl Error {
3847 pub fn code ( & self ) -> NonZeroU32 {
3948 self . 0
4049 }
50+
51+ fn msg ( & self ) -> Option < & ' static str > {
52+ if let Some ( msg) = super :: error_msg_inner ( self . 0 ) {
53+ Some ( msg)
54+ } else {
55+ match * self {
56+ ERROR_UNKNOWN => Some ( "getrandom: unknown error" ) ,
57+ ERROR_UNAVAILABLE => Some ( "getrandom: unavailable" ) ,
58+ _ => None
59+ }
60+ }
61+ }
62+ }
63+
64+ impl fmt:: Debug for Error {
65+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> Result < ( ) , fmt:: Error > {
66+ match self . msg ( ) {
67+ Some ( msg) => write ! ( f, "Error(\" {}\" )" , msg) ,
68+ None => write ! ( f, "Error(0x{:08X})" , self . 0 ) ,
69+ }
70+ }
4171}
4272
4373impl fmt:: Display for Error {
4474 fn fmt ( & self , f : & mut fmt:: Formatter ) -> Result < ( ) , fmt:: Error > {
45- match * self {
46- UNKNOWN_ERROR => write ! ( f, "Getrandom Error: unknown" ) ,
47- UNAVAILABLE_ERROR => write ! ( f, "Getrandom Error: unavailable" ) ,
48- code => write ! ( f, "Getrandom Error: {}" , code. 0 . get( ) ) ,
75+ match self . msg ( ) {
76+ Some ( msg) => write ! ( f, "{}" , msg) ,
77+ None => write ! ( f, "getrandom: unknown code 0x{:08X}" , self . 0 ) ,
4978 }
5079 }
5180}
@@ -63,22 +92,31 @@ impl From<io::Error> for Error {
6392 . and_then ( |code| NonZeroU32 :: new ( code as u32 ) )
6493 . map ( |code| Error ( code) )
6594 // in practice this should never happen
66- . unwrap_or ( UNKNOWN_ERROR )
95+ . unwrap_or ( ERROR_UNKNOWN )
6796 }
6897}
6998
7099#[ cfg( not( target_env = "sgx" ) ) ]
71100impl From < Error > for io:: Error {
72101 fn from ( err : Error ) -> Self {
73- match err {
74- UNKNOWN_ERROR => io:: Error :: new ( io:: ErrorKind :: Other ,
75- "getrandom error: unknown" ) ,
76- UNAVAILABLE_ERROR => io:: Error :: new ( io:: ErrorKind :: Other ,
77- "getrandom error: entropy source is unavailable" ) ,
78- code => io:: Error :: from_raw_os_error ( code. 0 . get ( ) as i32 ) ,
102+ match err. msg ( ) {
103+ Some ( msg) => io:: Error :: new ( io:: ErrorKind :: Other , msg) ,
104+ None => io:: Error :: from_raw_os_error ( err. 0 . get ( ) as i32 ) ,
79105 }
80106 }
81107}
82108
83109#[ cfg( not( target_env = "sgx" ) ) ]
84110impl error:: Error for Error { }
111+
112+ #[ cfg( test) ]
113+ mod tests {
114+ use std:: mem:: size_of;
115+ use super :: Error ;
116+
117+ #[ test]
118+ fn test_size ( ) {
119+ assert_eq ! ( size_of:: <Error >( ) , 4 ) ;
120+ assert_eq ! ( size_of:: <Result <( ) , Error >>( ) , 4 ) ;
121+ }
122+ }
0 commit comments