@@ -50,15 +50,12 @@ macro_rules! error_chain_processed {
50
50
}
51
51
52
52
) => {
53
- /// The Error type.
54
- ///
55
- /// This struct is made of three things:
56
- ///
57
- /// - an `ErrorKind` which is used to determine the type of the error.
58
- /// - a backtrace, generated when the error is created.
59
- /// - an error chain, used for the implementation of `Error::cause()`.
53
+ define_error!( $error_name, Inner ) ;
54
+
55
+ /// Separated for the `boxed-error` feature.
60
56
#[ derive( Debug ) ]
61
- pub struct $error_name {
57
+ #[ doc( hidden) ]
58
+ pub struct Inner {
62
59
// The members must be `pub` for `links`.
63
60
/// The kind of the error.
64
61
#[ doc( hidden) ]
@@ -68,16 +65,17 @@ macro_rules! error_chain_processed {
68
65
pub state: $crate:: State ,
69
66
}
70
67
68
+ impl Inner {
69
+ /// Used in From<ChainedError>.
70
+ pub fn into_raw( self ) -> ( $error_kind_name, $crate:: State ) {
71
+ ( self . kind, self . state)
72
+ }
73
+ }
74
+
71
75
impl $crate:: ChainedError for $error_name {
72
76
type ErrorKind = $error_kind_name;
73
77
74
- fn new( kind: $error_kind_name, state: $crate:: State ) -> $error_name {
75
- $error_name {
76
- kind: kind,
77
- state: state,
78
- }
79
- }
80
-
78
+ impl_chained_error_new!( $error_name, $error_kind_name) ;
81
79
impl_extract_backtrace!( $error_name
82
80
$error_kind_name
83
81
$( [ $link_error_path, $( #[ $meta_links] ) * ] ) * ) ;
@@ -87,15 +85,13 @@ macro_rules! error_chain_processed {
87
85
impl $error_name {
88
86
/// Constructs an error from a kind, and generates a backtrace.
89
87
pub fn from_kind( kind: $error_kind_name) -> $error_name {
90
- $error_name {
91
- kind: kind,
92
- state: $crate:: State :: default ( ) ,
93
- }
88
+ use $crate:: ChainedError ;
89
+ Self :: new( kind, $crate:: State :: default ( ) )
94
90
}
95
91
96
92
/// Returns the kind of the error.
97
93
pub fn kind( & self ) -> & $error_kind_name {
98
- & self . kind
94
+ & self . 0 . kind
99
95
}
100
96
101
97
/// Iterates over the error chain.
@@ -105,20 +101,20 @@ macro_rules! error_chain_processed {
105
101
106
102
/// Returns the backtrace associated with this error.
107
103
pub fn backtrace( & self ) -> Option <& $crate:: Backtrace > {
108
- self . state. backtrace( )
104
+ self . 0 . state. backtrace( )
109
105
}
110
106
}
111
107
112
108
impl :: std:: error:: Error for $error_name {
113
109
fn description( & self ) -> & str {
114
- self . kind. description( )
110
+ self . 0 . kind. description( )
115
111
}
116
112
117
113
fn cause( & self ) -> Option <& :: std:: error:: Error > {
118
- match self . state. next_error {
114
+ match self . 0 . state. next_error {
119
115
Some ( ref c) => Some ( & * * c) ,
120
116
None => {
121
- match self . kind {
117
+ match self . 0 . kind {
122
118
$(
123
119
$( #[ $meta_foreign_links] ) *
124
120
$error_kind_name:: $foreign_link_variant( ref foreign_err) => {
@@ -134,18 +130,17 @@ macro_rules! error_chain_processed {
134
130
135
131
impl :: std:: fmt:: Display for $error_name {
136
132
fn fmt( & self , f: & mut :: std:: fmt:: Formatter ) -> :: std:: fmt:: Result {
137
- :: std:: fmt:: Display :: fmt( & self . kind, f)
133
+ :: std:: fmt:: Display :: fmt( & self . 0 . kind, f)
138
134
}
139
135
}
140
136
141
137
$(
142
138
$( #[ $meta_links] ) *
143
139
impl From <$link_error_path> for $error_name {
144
140
fn from( e: $link_error_path) -> Self {
145
- $error_name {
146
- kind: $error_kind_name:: $link_variant( e. kind) ,
147
- state: e. state,
148
- }
141
+ use $crate:: ChainedError ;
142
+ let ( kind, state) = e. 0 . into_raw( ) ;
143
+ Self :: new( $error_kind_name:: $link_variant( kind) , state)
149
144
}
150
145
}
151
146
) *
@@ -183,7 +178,7 @@ macro_rules! error_chain_processed {
183
178
type Target = $error_kind_name;
184
179
185
180
fn deref( & self ) -> & Self :: Target {
186
- & self . kind
181
+ & self . 0 . kind
187
182
}
188
183
}
189
184
@@ -245,7 +240,7 @@ macro_rules! error_chain_processed {
245
240
246
241
impl From <$error_name> for $error_kind_name {
247
242
fn from( e: $error_name) -> Self {
248
- e. kind
243
+ e. 0 . kind
249
244
}
250
245
}
251
246
} ;
@@ -332,13 +327,13 @@ macro_rules! impl_extract_backtrace {
332
327
fn extract_backtrace( e: & ( :: std:: error:: Error + Send + ' static ) )
333
328
-> Option <Option <:: std:: sync:: Arc <$crate:: Backtrace >>> {
334
329
if let Some ( e) = e. downcast_ref:: <$error_name>( ) {
335
- return Some ( e. state. backtrace. clone( ) ) ;
330
+ return Some ( e. 0 . state. backtrace. clone( ) ) ;
336
331
}
337
332
$(
338
333
$( #[ $meta_links] ) *
339
334
{
340
335
if let Some ( e) = e. downcast_ref:: <$link_error_path>( ) {
341
- return Some ( e. state. backtrace. clone( ) ) ;
336
+ return Some ( e. 0 . state. backtrace. clone( ) ) ;
342
337
}
343
338
}
344
339
) *
@@ -360,3 +355,65 @@ macro_rules! impl_extract_backtrace {
360
355
$error_kind_name: ident
361
356
$( [ $link_error_path: path, $( #[ $meta_links: meta] ) * ] ) * ) => { }
362
357
}
358
+
359
+ #[ macro_export]
360
+ #[ doc( hidden) ]
361
+ #[ cfg( feature = "boxed-error" ) ]
362
+ macro_rules! impl_chained_error_new {
363
+ ( $error_name: ident, $error_kind_name: ident) => {
364
+ fn new( kind: $error_kind_name, state: $crate:: State ) -> $error_name {
365
+ $error_name( Box :: new( Inner {
366
+ kind: kind,
367
+ state: state,
368
+ } ) )
369
+ }
370
+ }
371
+ }
372
+
373
+ #[ macro_export]
374
+ #[ doc( hidden) ]
375
+ #[ cfg( not( feature = "boxed-error" ) ) ]
376
+ macro_rules! impl_chained_error_new {
377
+ ( $error_name: ident, $error_kind_name: ident) => {
378
+ fn new( kind: $error_kind_name, state: $crate:: State ) -> $error_name {
379
+ $error_name( Inner {
380
+ kind: kind,
381
+ state: state,
382
+ } )
383
+ }
384
+ }
385
+ }
386
+
387
+ #[ macro_export]
388
+ #[ doc( hidden) ]
389
+ #[ cfg( feature = "boxed-error" ) ]
390
+ macro_rules! define_error {
391
+ ( $error_name: ident, $inner_name: ident) => {
392
+ /// The Error type.
393
+ ///
394
+ /// This struct is made of three things:
395
+ ///
396
+ /// - an `ErrorKind` which is used to determine the type of the error.
397
+ /// - a backtrace, generated when the error is created.
398
+ /// - an error chain, used for the implementation of `Error::cause()`.
399
+ #[ derive( Debug ) ]
400
+ pub struct $error_name( pub Box <$inner_name>) ;
401
+ }
402
+ }
403
+
404
+ #[ macro_export]
405
+ #[ doc( hidden) ]
406
+ #[ cfg( not( feature = "boxed-error" ) ) ]
407
+ macro_rules! define_error {
408
+ ( $error_name: ident, $inner_name: ident) => {
409
+ /// The Error type.
410
+ ///
411
+ /// This struct is made of three things:
412
+ ///
413
+ /// - an `ErrorKind` which is used to determine the type of the error.
414
+ /// - a backtrace, generated when the error is created.
415
+ /// - an error chain, used for the implementation of `Error::cause()`.
416
+ #[ derive( Debug ) ]
417
+ pub struct $error_name( pub $inner_name) ;
418
+ }
419
+ }
0 commit comments