1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//! Procedural macros for the `dterror` crate. `#[derive(CtxError)]` generates code for error types.
//! `#[derive(FromContext)]` generates code for kind types.
//!
//! Use documentation is in the `dterror` crate.
use TokenStream;
use TokenStream as TokenStream2;
use format_ident;
use ;
/// Derives an implementation of `dterror::CtxError` for an error type.
///
/// For a struct, the macro generates:
///
/// - a `{Error}Ctx<'ctx>` struct that holds every field not marked with `#[source]`, `#[from]`, or
/// `#[location]`. By default, the generated type derives nothing. The container-level
/// `#[context(derive(...))]` attribute selects which traits the generated type derives.
/// - a `pub fn new(...)` constructor on `{Error}Ctx`. It takes one argument per context field, in
/// the declaration order.
/// - an `impl ::dterror::CtxError for {Error}`. The generated `from_context` moves the context
/// fields into the error and assigns `location` and `source` to the marked fields when the struct
/// has those fields. A `#[source]` field of type `Option<T>` receives the source wrapped in
/// `Some(source)`.
///
/// For an enum, the macro generates a `{Error}Ctx<'ctx>` **enum** instead. It creates one same-named
/// variant per *constructible* variant of the error (a variant with a `#[source]` or `#[from]`
/// field). It also creates one public associated constructor on `{Error}Ctx` per Ctx variant. The
/// macro gives each constructor the `snake_case` form of the variant name. A variant without a `#[source]`
/// or `#[from]` field gets no Ctx variant and no constructor.
///
/// # Attribute helpers
///
/// - `#[context(derive(Trait, ...))]`: container-level (on the struct or enum that you apply the
/// derive to). It selects which traits the generated `{Error}Ctx` derives. You can add trait
/// paths that `#[derive(...)]` itself accepts. The list replaces the default, so if you omit the
/// attribute, the derive adds no traits. This default means context field types do not need to
/// implement traits that call sites never use.
/// - `#[source]` or `#[from]`: the field that stores the source of the error. At most one per struct
/// or variant.
/// - `#[location]`: the field that stores the caller's [`std::panic::Location`]. At most one per
/// struct or variant.
/// - `#[context(option)]`: source-field-only. It wraps the captured source in
/// `::std::option::Option::Some(source)` when it builds the error. This is valid only on the
/// `#[source]`/`#[from]` field, which must have the type `Option<T>`. The macro applies the
/// wrapper automatically when the source field's type is already `Option<T>`. This helper only
/// records that the `Option<T>` type is intentional.
/// - `#[context(borrow = TargetType)]`: stores a borrowed reference (`&'ctx TargetType`) in Ctx
/// instead of an owned value. The macro allocates only inside `from_context`. When the caller
/// already holds a reference, the macro builds the context at no cost. Details are in
/// `CtxError::Ctx` in the `dterror` crate.
/// - `#[context(from = TargetType)]`: stores an owned value of type `TargetType` that is cheap to
/// construct, instead of the field's own type. The constructor takes `impl Into<TargetType>`, and
/// `from_context` converts the stored value to the field's owned type with `.into()`. If
/// `TargetType` includes lifetime parameters (for example `KindCtx<'a>`), the macro binds those
/// lifetimes to the `'ctx` lifetime parameter that `{Error}Ctx` carries.
/// - `#[context(constructor = "name")]`: variant-level. It renames the generated constructor for
/// that variant to `name`, a quoted string that parses as an identifier. At most one per variant.
///
/// A field may carry at most one `#[context(...)]` attribute, with at most one helper inside it. The
/// helpers `borrow` and `from` are mutually exclusive. The borrow and from helpers are also mutually
/// exclusive with a `location` marker. On a `#[source]`/`#[from]` field, the only accepted helper is
/// `option`. Every other field becomes part of the generated `{Error}Ctx`.
/// Derives an implementation of `dterror::FromContext` for a kind type (a plain, non-error type).
///
/// For a struct, the macro generates:
///
/// - a `{Kind}Ctx<'ctx>` struct that holds every field. By default, the generated type derives
/// nothing. The container-level `#[context(derive(...))]` attribute selects which traits the
/// generated type derives.
/// - a `pub fn new(...)` constructor that takes one argument per field, in the declaration order.
/// - an `impl From<{Kind}Ctx<'_>> for {Kind}` that converts the context to the kind. The generated
/// `From` implementation calls `.into()` on borrowed fields and from-marked surrogates.
/// - an `impl dterror::FromContext for {Kind}` that aliases the generated type.
///
/// For an enum, the macro generates a `{Kind}Ctx<'ctx>` **enum** instead. It creates one same-named
/// variant per variant (unit variants stay unit), plus one public associated constructor on
/// `{Kind}Ctx` per variant. The macro gives each constructor the `snake_case` form of the variant name.
///
/// # Attribute helpers
///
/// - `#[context(derive(Trait, ...))]`: container-level (on the struct or enum that you apply the
/// derive to). It selects which traits the generated `{Kind}Ctx` derives. You can add trait
/// paths that `#[derive(...)]` itself accepts. The list replaces the default, so if you omit the
/// attribute, the derive adds no traits. This default means context field types do not need to
/// implement traits that call sites never use.
/// - `#[context(borrow = TargetType)]`: stores a borrowed reference (`&'ctx TargetType`) in Ctx
/// instead of an owned value. The constructor takes the reference directly. The generated `From`
/// implementation converts the stored value to the field's owned type with `.into()`.
/// - `#[context(from = TargetType)]`: stores an owned value of type `TargetType` that is cheap to
/// construct, instead of the field's own type. The constructor takes `impl Into<TargetType>`. The
/// generated `From` implementation converts the stored value with `.into()`. If `TargetType`
/// includes lifetime parameters (for example `KindCtx<'a>`), the macro binds those lifetimes to
/// the `'ctx` lifetime parameter that `{Kind}Ctx` carries.
/// - `#[context(constructor = "name")]`: variant-level. It renames the generated constructor for
/// that variant to `name`, a quoted string that parses as an identifier. At most one per variant.
///
/// A field may carry at most one `#[context(...)]` attribute, with at most one helper inside it. The
/// helpers `borrow` and `from` are mutually exclusive. Every field of a kind becomes a context field.