1
1
#![ warn( missing_docs) ]
2
+ #![ cfg_attr( not( feature = "alloc" ) , no_std) ]
2
3
3
4
//! A library for consistent and reliable error handling
4
5
//!
28
29
//! * Instead of defining the custom `Error` type as an enum, it is a
29
30
//! struct containing an `ErrorKind` (which defines the
30
31
//! `description` and `display` methods for the error), an opaque,
31
- //! optional, boxed `std::error::Error + Send + 'static` object
32
+ //! optional, boxed `self:: std::error::Error + Send + 'static` object
32
33
//! (which defines the `cause`, and establishes the links in the
33
34
//! error chain), and a `Backtrace`.
34
35
//! * This crate additionally defines the trait `ResultExt`
35
36
//! that defines a `chain_err` method. This method
36
- //! on all `std::error::Error + Send + 'static` types extends
37
+ //! on all `self:: std::error::Error + Send + 'static` types extends
37
38
//! the error chain by boxing the current error into an opaque
38
39
//! object and putting it inside a new concrete error.
39
40
//! * It provides automatic `From` conversions between other error types
53
54
//! errors, requiring an `Into` or `From` conversion; as well as
54
55
//! slightly more cumbersome to match on errors with another layer
55
56
//! of types to match.
56
- //! * Because the error type contains `std::error::Error + Send + 'static` objects,
57
+ //! * Because the error type contains `self:: std::error::Error + Send + 'static` objects,
57
58
//! it can't implement `PartialEq` for easy comparisons.
58
59
//!
59
60
//! ## Quick start
182
183
//! following:
183
184
//!
184
185
//! ```ignore
185
- //! use std::error::Error as StdError;
186
- //! use std::sync::Arc;
186
+ //! use self:: std::error::Error as StdError;
187
+ //! use self:: std::sync::Arc;
187
188
//!
188
189
//! #[derive(Debug)]
189
190
//! pub struct Error(pub ErrorKind,
248
249
//!
249
250
//! Note that the return type is the typedef `Result`, which is
250
251
//! defined by the macro as `pub type Result<T> =
251
- //! ::std::result::Result<T, Error>`. Note that in both cases
252
+ //! ::self:: std::result::Result<T, Error>`. Note that in both cases
252
253
//! `.into()` is called to convert a type into the `Error` type; both
253
254
//! strings and `ErrorKind` have `From` conversions to turn them into
254
255
//! `Error`.
278
279
//! ```
279
280
//!
280
281
//! `chain_err` can be called on any `Result` type where the contained
281
- //! error type implements `std::error::Error + Send + 'static`. If
282
+ //! error type implements `self:: std::error::Error + Send + 'static`. If
282
283
//! the `Result` is an `Err` then `chain_err` evaluates the closure,
283
284
//! which returns *some type that can be converted to `ErrorKind`*,
284
285
//! boxes the original error to store as the cause, then returns a new
324
325
#[ cfg( feature = "backtrace" ) ]
325
326
extern crate backtrace;
326
327
327
- use std:: error;
328
- use std:: iter:: Iterator ;
328
+ #[ cfg( feature = "alloc" ) ]
329
+ pub use std;
330
+ #[ cfg( not( feature = "alloc" ) ) ]
331
+ pub extern crate core as std;
332
+
333
+ use self :: std:: iter:: Iterator ;
329
334
#[ cfg( feature = "backtrace" ) ]
330
- use std:: sync:: Arc ;
335
+ use self :: std:: sync:: Arc ;
331
336
332
337
#[ cfg( feature = "backtrace" ) ]
333
338
pub use backtrace:: Backtrace ;
@@ -336,12 +341,12 @@ mod quick_error;
336
341
mod error_chain;
337
342
338
343
/// Iterator over the error chain.
339
- pub struct ErrorChainIter < ' a > ( pub Option < & ' a error :: Error > ) ;
344
+ pub struct ErrorChainIter < ' a > ( pub Option < & ' a Error > ) ;
340
345
341
346
impl < ' a > Iterator for ErrorChainIter < ' a > {
342
- type Item = & ' a error :: Error ;
347
+ type Item = & ' a Error ;
343
348
344
- fn next < ' b > ( & ' b mut self ) -> Option < & ' a error :: Error > {
349
+ fn next < ' b > ( & ' b mut self ) -> Option < & ' a Error > {
345
350
match self . 0 . take ( ) {
346
351
Some ( e) => {
347
352
self . 0 = e. cause ( ) ;
@@ -358,65 +363,81 @@ impl<'a> Iterator for ErrorChainIter<'a> {
358
363
#[ cfg( feature = "backtrace" ) ]
359
364
#[ doc( hidden) ]
360
365
pub fn make_backtrace ( ) -> Option < Arc < Backtrace > > {
361
- match std:: env:: var_os ( "RUST_BACKTRACE" ) {
366
+ match self :: std:: env:: var_os ( "RUST_BACKTRACE" ) {
362
367
Some ( ref val) if val != "0" => Some ( Arc :: new ( Backtrace :: new ( ) ) ) ,
363
368
_ => None
364
369
}
365
370
}
366
371
367
372
/// This trait is implemented on all the errors generated by the `error_chain`
368
373
/// macro.
369
- pub trait ChainedError : error :: Error + Send + ' static {
374
+ pub trait ChainedError : Error + Send + ' static {
370
375
/// Associated kind type.
371
376
type ErrorKind ;
372
377
/// Creates an error from it's parts.
373
378
fn new ( kind : Self :: ErrorKind , state : State ) -> Self ;
374
379
/// Returns the first known backtrace, either from it's State or from one
375
380
/// of the errors from `foreign_links`.
376
381
#[ cfg( feature = "backtrace" ) ]
377
- fn extract_backtrace ( e : & ( error :: Error + Send + ' static ) )
382
+ fn extract_backtrace ( e : & ( Error + Send + ' static ) )
378
383
-> Option < Option < Arc < Backtrace > > > ;
379
384
}
380
385
381
- /// Additionnal methods for `Result`, for easy interaction with this crate.
382
- pub trait ResultExt < T , E : ChainedError > {
383
- /// If the `Result` is an `Err` then `chain_err` evaluates the closure,
384
- /// which returns *some type that can be converted to `ErrorKind`*, boxes
385
- /// the original error to store as the cause, then returns a new error
386
- /// containing the original error.
387
- fn chain_err < F , EK > ( self , callback : F ) -> Result < T , E >
388
- where F : FnOnce ( ) -> EK ,
389
- EK : Into < E :: ErrorKind > ;
390
- }
386
+ pub use alloc:: * ;
387
+
388
+ #[ cfg( feature = "alloc" ) ]
389
+ mod alloc {
390
+ pub use std:: error:: Error ;
391
391
392
- impl < T , E > ResultExt < T , E > for Result < T , E > where E : ChainedError {
393
- fn chain_err < F , EK > ( self , callback : F ) -> Result < T , E >
394
- where F : FnOnce ( ) -> EK ,
395
- EK : Into < E :: ErrorKind > {
396
- self . map_err ( move |e| {
397
- #[ cfg( feature = "backtrace" ) ]
398
- let error = {
399
- let backtrace = E :: extract_backtrace ( & e)
400
- . unwrap_or_else ( make_backtrace) ;
401
- E :: new ( callback ( ) . into ( ) , State {
402
- next_error : Some ( Box :: new ( e) ) ,
403
- backtrace : backtrace,
392
+ /// Additionnal methods for `Result`, for easy interaction with this crate.
393
+ pub trait ResultExt < T , E : ChainedError > {
394
+ /// If the `Result` is an `Err` then `chain_err` evaluates the closure,
395
+ /// which returns *some type that can be converted to `ErrorKind`*, boxes
396
+ /// the original error to store as the cause, then returns a new error
397
+ /// containing the original error.
398
+ fn chain_err < F , EK > ( self , callback : F ) -> Result < T , E >
399
+ where F : FnOnce ( ) -> EK ,
400
+ EK : Into < E :: ErrorKind > ;
401
+ }
402
+
403
+ impl < T , E > ResultExt < T , E > for Result < T , E > where E : ChainedError {
404
+ fn chain_err < F , EK > ( self , callback : F ) -> Result < T , E >
405
+ where F : FnOnce ( ) -> EK ,
406
+ EK : Into < E :: ErrorKind > {
407
+ self . map_err ( move |e| {
408
+ #[ cfg( feature = "backtrace" ) ]
409
+ let error = {
410
+ let backtrace = E :: extract_backtrace ( & e)
411
+ . unwrap_or_else ( make_backtrace) ;
412
+ E :: new ( callback ( ) . into ( ) , State {
413
+ next_error : Some ( Box :: new ( e) ) ,
414
+ backtrace : backtrace,
415
+ } )
416
+ } ;
417
+ #[ cfg( not( feature = "backtrace" ) ) ]
418
+ let error = E :: new ( callback ( ) . into ( ) , State {
419
+ next_error : Some ( Box :: new ( e) ) ,
420
+ } ) ;
421
+ error
404
422
} )
405
- } ;
406
- #[ cfg( not( feature = "backtrace" ) ) ]
407
- let error = E :: new ( callback ( ) . into ( ) , State {
408
- next_error : Some ( Box :: new ( e) ) ,
409
- } ) ;
410
- error
411
- } )
423
+ }
412
424
}
413
425
}
414
426
427
+ #[ cfg( not( feature = "alloc" ) ) ]
428
+ mod alloc {
429
+ pub trait Error {
430
+ fn description ( & self ) -> & str ;
431
+
432
+ fn cause ( & self ) -> Option < & Error > { None }
433
+ }
434
+ }
415
435
416
436
/// Common state between errors.
417
437
#[ derive( Debug ) ]
418
438
pub struct State {
419
439
/// Next error in the error chain.
440
+ #[ cfg( feature = "alloc" ) ]
420
441
pub next_error : Option < Box < error:: Error + Send > > ,
421
442
/// Backtrace for the current error.
422
443
#[ cfg( feature = "backtrace" ) ]
@@ -430,10 +451,13 @@ impl Default for State {
430
451
next_error : None ,
431
452
backtrace : make_backtrace ( ) ,
432
453
} ;
433
- #[ cfg( not( feature = "backtrace" ) ) ]
454
+ #[ cfg( all ( not( feature = "backtrace" ) , feature = "alloc ") ) ]
434
455
let state = State {
435
456
next_error : None ,
436
457
} ;
458
+ #[ cfg( not( feature = "alloc" ) ) ]
459
+ let state = State {
460
+ } ;
437
461
state
438
462
}
439
463
}
0 commit comments