@@ -32,6 +32,11 @@ often [`From` as well](crate::From).
32
32
called ` Backtrace ` . Then it would return that field as the ` backtrace ` .
33
33
3 . One of the fields is annotated with ` #[error(backtrace)] ` . Then it would
34
34
return that field as the ` backtrace ` .
35
+ 4 . The source field is annotated with ` #[error(backtrace)] ` . Then it would
36
+ forward implementation to the source.
37
+
38
+ If the source field is annotated with ` #[error(backtrace)] ` , and another field
39
+ is also annotated/was inferred, both backtraces will be provided.
35
40
36
41
### Ignoring fields for derives
37
42
@@ -41,6 +46,11 @@ detecting `backtrace` and `source`. It's also possible to mark a field only
41
46
ignored for one of these methods by using ` #[error(not(backtrace))] ` or
42
47
` #[error(not(source))] ` .
43
48
49
+ ### Source Forwarding
50
+
51
+ A struct, enum, or enum variant can be annotated with ` #[error(forward)] ` to forward
52
+ the ` source() ` implementation to the source field (inferred or explicitly annotated),
53
+ instead of returning the field itself.
44
54
45
55
### What works in ` no_std ` ?
46
56
@@ -126,6 +136,17 @@ enum CompoundError {
126
136
},
127
137
Tuple (WithExplicitSource ),
128
138
WithoutSource (#[error(not(source))] Tuple ),
139
+ #[error(forward)]
140
+ #[from(ignore)]
141
+ ForwardedImplicitSource {
142
+ source : WithSource ,
143
+ },
144
+ #[error(forward)]
145
+ #[from(ignore)]
146
+ ForwardedExplicitSourceWithBacktrace {
147
+ #[error(source, backtrace)]
148
+ explicit_source : WithSourceAndBacktrace ,
149
+ }
129
150
}
130
151
131
152
assert! (Simple . source (). is_none ());
@@ -146,5 +167,14 @@ assert!(CompoundError::from(Simple).source().is_some());
146
167
assert! (CompoundError :: from (WithSource :: default ()). source (). is_some ());
147
168
assert! (CompoundError :: from (WithExplicitSource :: default ()). source (). is_some ());
148
169
assert! (CompoundError :: from (Tuple :: default ()). source (). is_none ());
170
+
171
+ let forwarded = CompoundError :: ForwardedImplicitSource { source : WithSource :: default () };
172
+ assert! (forwarded . source (). is_some ());
173
+ assert! (forwarded . source (). unwrap (). is :: <Simple >());
174
+
175
+ let forwarded_with_backtrace = CompoundError :: ForwardedExplicitSourceWithBacktrace { explicit_source : WithSourceAndBacktrace { source : Simple , backtrace : Backtrace :: capture () } };
176
+ assert! (forwarded_with_backtrace . source (). is_some ());
177
+ assert! (forwarded_with_backtrace . source (). unwrap (). is :: <Simple >());
178
+ assert! (any :: request_ref :: <Backtrace >(& forwarded_with_backtrace ). is_some ());
149
179
# }
150
180
```
0 commit comments