@@ -12,20 +12,29 @@ use core::fmt;
12
12
#[ cfg( not( target_env = "sgx" ) ) ]
13
13
use std:: { io, error} ;
14
14
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
+
15
20
/// 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 )
18
25
} ) ;
19
26
20
27
/// 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 )
23
32
} ) ;
24
33
25
34
/// The error type.
26
35
///
27
36
/// This type is small and no-std compatible.
28
- #[ derive( Copy , Clone , Debug , Eq , PartialEq ) ]
37
+ #[ derive( Copy , Clone , Eq , PartialEq ) ]
29
38
pub struct Error ( NonZeroU32 ) ;
30
39
31
40
impl Error {
@@ -38,14 +47,34 @@ impl Error {
38
47
pub fn code ( & self ) -> NonZeroU32 {
39
48
self . 0
40
49
}
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
+ }
41
71
}
42
72
43
73
impl fmt:: Display for Error {
44
74
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 ) ,
49
78
}
50
79
}
51
80
}
@@ -63,22 +92,31 @@ impl From<io::Error> for Error {
63
92
. and_then ( |code| NonZeroU32 :: new ( code as u32 ) )
64
93
. map ( |code| Error ( code) )
65
94
// in practice this should never happen
66
- . unwrap_or ( UNKNOWN_ERROR )
95
+ . unwrap_or ( ERROR_UNKNOWN )
67
96
}
68
97
}
69
98
70
99
#[ cfg( not( target_env = "sgx" ) ) ]
71
100
impl From < Error > for io:: Error {
72
101
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 ) ,
79
105
}
80
106
}
81
107
}
82
108
83
109
#[ cfg( not( target_env = "sgx" ) ) ]
84
110
impl 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