@@ -13,32 +13,21 @@ use core::num::NonZeroU32;
13
13
/// The [`Error::raw_os_error()`] will indicate if the error is from the OS, and
14
14
/// if so, which error code the OS gave the application. If such an error is
15
15
/// encountered, please consult with your system documentation.
16
+ ///
17
+ /// Internally this type is a NonZeroU32, with certain values reserved for
18
+ /// certain purposes, see [`Error::INTERNAL_START`] and [`Error::CUSTOM_START`].
16
19
#[ derive( Copy , Clone , Eq , PartialEq ) ]
17
20
pub struct Error ( NonZeroU32 ) ;
18
21
19
- // This NonZeroU32 in Error has enough room for two types of errors:
20
- // - OS Errors: in range [1, 1 << 31) (i.e. positive i32 values)
21
- // - Custom Errors: in range [1 << 31, 1 << 32) (in blocks of 1 << 16)
22
- const CUSTOM_START : u32 = 1 << 31 ;
23
- const BLOCK_SIZE : u32 = 1 << 16 ;
24
-
25
22
impl Error {
26
- /// Create a new error from a raw OS error number (errno).
27
- #[ inline]
28
- pub fn from_os_error ( errno : i32 ) -> Self {
29
- assert ! ( errno > 0 ) ;
30
- Self ( NonZeroU32 :: new ( errno as u32 ) . unwrap ( ) )
31
- }
23
+ /// Codes below this point represent OS Errors (i.e. positive i32 values).
24
+ /// Codes at or above this point, but below [`Error::CUSTOM_START`] are
25
+ /// reserved for use by the `rand` and `getrandom` crates.
26
+ pub const INTERNAL_START : u32 = 1 << 31 ;
32
27
33
- /// Crate a custom error in the provided block (group of 2^16 error codes).
34
- /// The provided block must not be negative, and block 0 is reserved for
35
- /// custom errors in the `getrandom` crate.
36
- #[ inline]
37
- pub fn custom_error ( block : i16 , code : u16 ) -> Self {
38
- assert ! ( block >= 0 ) ;
39
- let n = CUSTOM_START + ( block as u16 as u32 ) * BLOCK_SIZE + ( code as u32 ) ;
40
- Self ( NonZeroU32 :: new ( n) . unwrap ( ) )
41
- }
28
+ /// Codes at or above this point can be used by users to define their own
29
+ /// custom errors.
30
+ pub const CUSTOM_START : u32 = ( 1 << 31 ) + ( 1 << 30 ) ;
42
31
43
32
/// Extract the raw OS error code (if this error came from the OS)
44
33
///
@@ -47,33 +36,21 @@ impl Error {
47
36
/// error value can still be formatted via the `Diplay` implementation.
48
37
#[ inline]
49
38
pub fn raw_os_error ( & self ) -> Option < i32 > {
50
- self . try_os_error ( ) . ok ( )
39
+ if self . 0 . get ( ) < Self :: INTERNAL_START {
40
+ Some ( self . 0 . get ( ) as i32 )
41
+ } else {
42
+ None
43
+ }
51
44
}
52
45
53
46
/// Extract the bare error code.
54
47
///
55
48
/// This code can either come from the underlying OS, or be a custom error.
56
- /// Use [`raw_os_error()`] to disambiguate.
49
+ /// Use [`Error:: raw_os_error()`] to disambiguate.
57
50
#[ inline]
58
51
pub fn code ( & self ) -> NonZeroU32 {
59
52
self . 0
60
53
}
61
-
62
- /// Helper method for creating internal errors
63
- #[ allow( dead_code) ]
64
- pub ( crate ) fn internal ( code : u16 ) -> Self {
65
- Self :: custom_error ( 0 , code)
66
- }
67
-
68
- /// Returns either the OS error or a (block, code) pair
69
- fn try_os_error ( & self ) -> Result < i32 , ( i16 , u16 ) > {
70
- if self . 0 . get ( ) < CUSTOM_START {
71
- Ok ( self . 0 . get ( ) as i32 )
72
- } else {
73
- let offset = self . 0 . get ( ) - CUSTOM_START ;
74
- Err ( ( ( offset / BLOCK_SIZE ) as i16 , ( offset % BLOCK_SIZE ) as u16 ) )
75
- }
76
- }
77
54
}
78
55
79
56
#[ cfg( any( unix, target_os = "redox" ) ) ]
@@ -96,44 +73,34 @@ fn os_err_desc(_errno: i32, _buf: &mut [u8]) -> Option<&str> {
96
73
impl fmt:: Debug for Error {
97
74
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
98
75
let mut dbg = f. debug_struct ( "Error" ) ;
99
- match self . try_os_error ( ) {
100
- Ok ( errno) => {
101
- dbg. field ( "os_error" , & errno) ;
102
- let mut buf = [ 0u8 ; 128 ] ;
103
- if let Some ( desc) = os_err_desc ( errno, & mut buf) {
104
- dbg. field ( "description" , & desc) ;
105
- }
106
- }
107
- Err ( ( 0 , code) ) => {
108
- dbg. field ( "internal_code" , & code) ;
109
- if let Some ( desc) = internal_desc ( code) {
110
- dbg. field ( "description" , & desc) ;
111
- }
112
- }
113
- Err ( ( block, code) ) => {
114
- dbg. field ( "block" , & block) ;
115
- dbg. field ( "custom_code" , & code) ;
76
+ if let Some ( errno) = self . raw_os_error ( ) {
77
+ dbg. field ( "os_error" , & errno) ;
78
+ let mut buf = [ 0u8 ; 128 ] ;
79
+ if let Some ( desc) = os_err_desc ( errno, & mut buf) {
80
+ dbg. field ( "description" , & desc) ;
116
81
}
82
+ } else if let Some ( desc) = internal_desc ( * self ) {
83
+ dbg. field ( "internal_code" , & self . 0 . get ( ) ) ;
84
+ dbg. field ( "description" , & desc) ;
85
+ } else {
86
+ dbg. field ( "unknown_code" , & self . 0 . get ( ) ) ;
117
87
}
118
88
dbg. finish ( )
119
89
}
120
90
}
121
91
122
92
impl fmt:: Display for Error {
123
93
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
124
- match self . try_os_error ( ) {
125
- Ok ( errno) => {
126
- let mut buf = [ 0u8 ; 128 ] ;
127
- match os_err_desc ( errno, & mut buf) {
128
- Some ( desc) => f. write_str ( desc) ,
129
- None => write ! ( f, "OS Error: {}" , errno) ,
130
- }
131
- }
132
- Err ( ( 0 , code) ) => match internal_desc ( code) {
94
+ if let Some ( errno) = self . raw_os_error ( ) {
95
+ let mut buf = [ 0u8 ; 128 ] ;
96
+ match os_err_desc ( errno, & mut buf) {
133
97
Some ( desc) => f. write_str ( desc) ,
134
- None => write ! ( f, "Internal Error: {}" , code) ,
135
- } ,
136
- Err ( ( block, code) ) => write ! ( f, "Custom Error: block={}, code={}" , block, code) ,
98
+ None => write ! ( f, "OS Error: {}" , errno) ,
99
+ }
100
+ } else if let Some ( desc) = internal_desc ( * self ) {
101
+ f. write_str ( desc)
102
+ } else {
103
+ write ! ( f, "Unknown Error: {}" , self . 0 . get( ) )
137
104
}
138
105
}
139
106
}
@@ -145,19 +112,23 @@ impl From<NonZeroU32> for Error {
145
112
}
146
113
147
114
/// Internal Error constants
148
- pub ( crate ) const UNSUPPORTED : u16 = 0 ;
149
- pub ( crate ) const UNKNOWN_IO_ERROR : u16 = 1 ;
150
- pub ( crate ) const SEC_RANDOM_FAILED : u16 = 2 ;
151
- pub ( crate ) const RTL_GEN_RANDOM_FAILED : u16 = 3 ;
152
- pub ( crate ) const FAILED_RDRAND : u16 = 4 ;
153
- pub ( crate ) const NO_RDRAND : u16 = 5 ;
154
- pub ( crate ) const BINDGEN_CRYPTO_UNDEF : u16 = 6 ;
155
- pub ( crate ) const BINDGEN_GRV_UNDEF : u16 = 7 ;
156
- pub ( crate ) const STDWEB_NO_RNG : u16 = 8 ;
157
- pub ( crate ) const STDWEB_RNG_FAILED : u16 = 9 ;
158
-
159
- fn internal_desc ( code : u16 ) -> Option < & ' static str > {
160
- match code {
115
+ pub ( crate ) const UNSUPPORTED : Error = internal_error ( 0 ) ;
116
+ pub ( crate ) const UNKNOWN_IO_ERROR : Error = internal_error ( 1 ) ;
117
+ pub ( crate ) const SEC_RANDOM_FAILED : Error = internal_error ( 2 ) ;
118
+ pub ( crate ) const RTL_GEN_RANDOM_FAILED : Error = internal_error ( 3 ) ;
119
+ pub ( crate ) const FAILED_RDRAND : Error = internal_error ( 4 ) ;
120
+ pub ( crate ) const NO_RDRAND : Error = internal_error ( 5 ) ;
121
+ pub ( crate ) const BINDGEN_CRYPTO_UNDEF : Error = internal_error ( 6 ) ;
122
+ pub ( crate ) const BINDGEN_GRV_UNDEF : Error = internal_error ( 7 ) ;
123
+ pub ( crate ) const STDWEB_NO_RNG : Error = internal_error ( 8 ) ;
124
+ pub ( crate ) const STDWEB_RNG_FAILED : Error = internal_error ( 9 ) ;
125
+
126
+ const fn internal_error ( n : u16 ) -> Error {
127
+ Error ( unsafe { NonZeroU32 :: new_unchecked ( Error :: INTERNAL_START + n as u32 ) } )
128
+ }
129
+
130
+ fn internal_desc ( error : Error ) -> Option < & ' static str > {
131
+ match error {
161
132
UNSUPPORTED => Some ( "getrandom: this target is not supported" ) ,
162
133
UNKNOWN_IO_ERROR => Some ( "Unknown std::io::Error" ) ,
163
134
SEC_RANDOM_FAILED => Some ( "SecRandomCopyBytes: call failed" ) ,
0 commit comments