@@ -129,9 +129,7 @@ impl Error {
129
129
///
130
130
/// This function is used to generically create I/O errors which do not
131
131
/// originate from the OS itself. The `error` argument is an arbitrary
132
- /// payload which will be contained in this `Error`. Accessors as well as
133
- /// downcasting will soon be added to this type as well to access the custom
134
- /// information.
132
+ /// payload which will be contained in this `Error`.
135
133
///
136
134
/// # Examples
137
135
///
@@ -174,8 +172,9 @@ impl Error {
174
172
175
173
/// Returns the OS error that this error represents (if any).
176
174
///
177
- /// If this `Error` was constructed via `last_os_error` then this function
178
- /// will return `Some`, otherwise it will return `None`.
175
+ /// If this `Error` was constructed via `last_os_error` or
176
+ /// `from_raw_os_error`, then this function will return `Some`, otherwise
177
+ /// it will return `None`.
179
178
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
180
179
pub fn raw_os_error ( & self ) -> Option < i32 > {
181
180
match self . repr {
@@ -184,6 +183,46 @@ impl Error {
184
183
}
185
184
}
186
185
186
+ /// Returns a reference to the inner error wrapped by this error (if any).
187
+ ///
188
+ /// If this `Error` was constructed via `new` then this function will
189
+ /// return `Some`, otherwise it will return `None`.
190
+ #[ unstable( feature = "io_error_inner" ,
191
+ reason = "recently added and requires UFCS to downcast" ) ]
192
+ pub fn get_ref ( & self ) -> Option < & ( error:: Error +Send +Sync +' static ) > {
193
+ match self . repr {
194
+ Repr :: Os ( ..) => None ,
195
+ Repr :: Custom ( ref c) => Some ( & * c. error ) ,
196
+ }
197
+ }
198
+
199
+ /// Returns a mutable reference to the inner error wrapped by this error
200
+ /// (if any).
201
+ ///
202
+ /// If this `Error` was constructed via `new` then this function will
203
+ /// return `Some`, otherwise it will return `None`.
204
+ #[ unstable( feature = "io_error_inner" ,
205
+ reason = "recently added and requires UFCS to downcast" ) ]
206
+ pub fn get_mut ( & mut self ) -> Option < & mut ( error:: Error +Send +Sync +' static ) > {
207
+ match self . repr {
208
+ Repr :: Os ( ..) => None ,
209
+ Repr :: Custom ( ref mut c) => Some ( & mut * c. error ) ,
210
+ }
211
+ }
212
+
213
+ /// Consumes the `Error`, returning its inner error (if any).
214
+ ///
215
+ /// If this `Error` was constructed via `new` then this function will
216
+ /// return `Some`, otherwise it will return `None`.
217
+ #[ unstable( feature = "io_error_inner" ,
218
+ reason = "recently added and requires UFCS to downcast" ) ]
219
+ pub fn into_inner ( self ) -> Option < Box < error:: Error +Send +Sync > > {
220
+ match self . repr {
221
+ Repr :: Os ( ..) => None ,
222
+ Repr :: Custom ( c) => Some ( c. error )
223
+ }
224
+ }
225
+
187
226
/// Returns the corresponding `ErrorKind` for this error.
188
227
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
189
228
pub fn kind ( & self ) -> ErrorKind {
@@ -215,9 +254,52 @@ impl error::Error for Error {
215
254
Repr :: Custom ( ref c) => c. error . description ( ) ,
216
255
}
217
256
}
257
+
258
+ fn cause ( & self ) -> Option < & error:: Error > {
259
+ match self . repr {
260
+ Repr :: Os ( ..) => None ,
261
+ Repr :: Custom ( ref c) => c. error . cause ( ) ,
262
+ }
263
+ }
218
264
}
219
265
220
266
fn _assert_error_is_sync_send ( ) {
221
267
fn _is_sync_send < T : Sync +Send > ( ) { }
222
268
_is_sync_send :: < Error > ( ) ;
223
269
}
270
+
271
+ #[ cfg( test) ]
272
+ mod test {
273
+ use prelude:: v1:: * ;
274
+ use super :: { Error , ErrorKind } ;
275
+ use error;
276
+ use error:: Error as error_Error;
277
+ use fmt;
278
+
279
+ #[ test]
280
+ fn test_downcasting ( ) {
281
+ #[ derive( Debug ) ]
282
+ struct TestError ;
283
+
284
+ impl fmt:: Display for TestError {
285
+ fn fmt ( & self , fmt : & mut fmt:: Formatter ) -> fmt:: Result {
286
+ Ok ( ( ) )
287
+ }
288
+ }
289
+
290
+ impl error:: Error for TestError {
291
+ fn description ( & self ) -> & str {
292
+ "asdf"
293
+ }
294
+ }
295
+
296
+ // we have to call all of these UFCS style right now since method
297
+ // resolution won't implicitly drop the Send+Sync bounds
298
+ let mut err = Error :: new ( ErrorKind :: Other , TestError ) ;
299
+ assert ! ( error:: Error :: is:: <TestError >( err. get_ref( ) . unwrap( ) ) ) ;
300
+ assert_eq ! ( "asdf" , err. get_ref( ) . unwrap( ) . description( ) ) ;
301
+ assert ! ( error:: Error :: is:: <TestError >( err. get_mut( ) . unwrap( ) ) ) ;
302
+ let extracted = err. into_inner ( ) . unwrap ( ) ;
303
+ error:: Error :: downcast :: < TestError > ( extracted) . unwrap ( ) ;
304
+ }
305
+ }
0 commit comments