derive_more_impl/
lib.rs

1#![doc = include_str!("../README.md")]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3#![recursion_limit = "128"]
4#![cfg_attr(any(not(docsrs), ci), deny(rustdoc::all))]
5#![forbid(non_ascii_idents, unsafe_code)]
6#![warn(clippy::nonstandard_macro_braces)]
7
8use proc_macro::TokenStream;
9use syn::parse::Error as ParseError;
10
11mod utils;
12
13#[cfg(feature = "as_ref")]
14mod r#as;
15#[cfg(feature = "eq")]
16mod cmp;
17#[cfg(feature = "constructor")]
18mod constructor;
19#[cfg(feature = "deref")]
20mod deref;
21#[cfg(feature = "deref_mut")]
22mod deref_mut;
23#[cfg(feature = "error")]
24mod error;
25#[cfg(any(feature = "debug", feature = "display"))]
26mod fmt;
27#[cfg(feature = "from")]
28mod from;
29#[cfg(feature = "from_str")]
30mod from_str;
31#[cfg(feature = "index")]
32mod index;
33#[cfg(feature = "index_mut")]
34mod index_mut;
35#[cfg(feature = "into")]
36mod into;
37#[cfg(feature = "into_iterator")]
38mod into_iterator;
39#[cfg(feature = "is_variant")]
40mod is_variant;
41#[cfg(feature = "not")]
42mod not_like;
43#[cfg(any(
44    feature = "add",
45    feature = "add_assign",
46    feature = "mul",
47    feature = "mul_assign"
48))]
49mod ops;
50#[cfg(any(feature = "debug", feature = "display"))]
51pub(crate) mod parsing;
52#[cfg(feature = "sum")]
53mod sum_like;
54#[cfg(feature = "try_from")]
55mod try_from;
56#[cfg(feature = "try_into")]
57mod try_into;
58#[cfg(feature = "try_unwrap")]
59mod try_unwrap;
60#[cfg(feature = "unwrap")]
61mod unwrap;
62
63// This trait describes the possible return types of
64// the derives. A derive can generally be infallible and
65// return a TokenStream, or it can be fallible and return
66// a Result<TokenStream, syn::parse::Error>.
67//
68// This trait can be unused if no feature is enabled. We already error in that case but this
69// warning distracts from the actual error.
70#[allow(dead_code)]
71trait Output {
72    fn process(self) -> TokenStream;
73}
74
75impl Output for proc_macro2::TokenStream {
76    fn process(self) -> TokenStream {
77        self.into()
78    }
79}
80
81impl Output for Result<proc_macro2::TokenStream, ParseError> {
82    fn process(self) -> TokenStream {
83        match self {
84            Ok(ts) => ts.into(),
85            Err(e) => e.to_compile_error().into(),
86        }
87    }
88}
89
90macro_rules! create_derive(
91    ($feature:literal, $mod_:ident $(:: $mod_rest:ident)*, $trait_:ident, $fn_name: ident $(,$attribute:ident)* $(,)?) => {
92        #[cfg(feature = $feature)]
93        #[proc_macro_derive($trait_, attributes($($attribute),*))]
94        #[doc = include_str!(concat!("../doc/", $feature, ".md"))]
95        pub fn $fn_name(input: TokenStream) -> TokenStream {
96            let ast = syn::parse(input).unwrap();
97            Output::process($mod_$(:: $mod_rest)*::expand(&ast, stringify!($trait_)))
98        }
99    }
100);
101
102create_derive!("add", ops::add, Add, add_derive, add);
103create_derive!("add", ops::add, Sub, sub_derive, sub);
104create_derive!("add", ops::add, BitAnd, bit_and_derive, bitand);
105create_derive!("add", ops::add, BitOr, bit_or_derive, bitor);
106create_derive!("add", ops::add, BitXor, bit_xor_derive, bitxor);
107
108create_derive!(
109    "add_assign",
110    ops::add_assign,
111    AddAssign,
112    add_assign_derive,
113    add_assign,
114);
115create_derive!(
116    "add_assign",
117    ops::add_assign,
118    SubAssign,
119    sub_assign_derive,
120    sub_assign,
121);
122create_derive!(
123    "add_assign",
124    ops::add_assign,
125    BitAndAssign,
126    bit_and_assign_derive,
127    bitand_assign,
128);
129create_derive!(
130    "add_assign",
131    ops::add_assign,
132    BitOrAssign,
133    bit_or_assign_derive,
134    bitor_assign,
135);
136create_derive!(
137    "add_assign",
138    ops::add_assign,
139    BitXorAssign,
140    bit_xor_assign_derive,
141    bitxor_assign,
142);
143
144create_derive!("as_ref", r#as::r#mut, AsMut, as_mut_derive, as_mut);
145create_derive!("as_ref", r#as::r#ref, AsRef, as_ref_derive, as_ref);
146
147create_derive!("constructor", constructor, Constructor, constructor_derive);
148
149create_derive!("debug", fmt::debug, Debug, debug_derive, debug);
150
151create_derive!("deref", deref, Deref, deref_derive, deref);
152
153create_derive!(
154    "deref_mut",
155    deref_mut,
156    DerefMut,
157    deref_mut_derive,
158    deref_mut,
159);
160
161create_derive!("display", fmt::display, Display, display_derive, display);
162create_derive!("display", fmt::display, Binary, binary_derive, binary);
163create_derive!("display", fmt::display, Octal, octal_derive, octal);
164create_derive!(
165    "display",
166    fmt::display,
167    LowerHex,
168    lower_hex_derive,
169    lower_hex,
170);
171create_derive!(
172    "display",
173    fmt::display,
174    UpperHex,
175    upper_hex_derive,
176    upper_hex,
177);
178create_derive!(
179    "display",
180    fmt::display,
181    LowerExp,
182    lower_exp_derive,
183    lower_exp,
184);
185create_derive!(
186    "display",
187    fmt::display,
188    UpperExp,
189    upper_exp_derive,
190    upper_exp,
191);
192create_derive!("display", fmt::display, Pointer, pointer_derive, pointer);
193
194create_derive!("eq", cmp::eq, Eq, eq_derive, eq);
195create_derive!(
196    "eq",
197    cmp::partial_eq,
198    PartialEq,
199    partial_eq_derive,
200    partial_eq,
201);
202
203create_derive!("error", error, Error, error_derive, error);
204
205create_derive!("from", from, From, from_derive, from);
206
207create_derive!("from_str", from_str, FromStr, from_str_derive, from_str);
208
209create_derive!("index", index, Index, index_derive, index);
210
211create_derive!(
212    "index_mut",
213    index_mut,
214    IndexMut,
215    index_mut_derive,
216    index_mut,
217);
218
219create_derive!("into", into, Into, into_derive, into);
220
221create_derive!(
222    "into_iterator",
223    into_iterator,
224    IntoIterator,
225    into_iterator_derive,
226    into_iterator,
227);
228
229create_derive!(
230    "is_variant",
231    is_variant,
232    IsVariant,
233    is_variant_derive,
234    is_variant,
235);
236
237create_derive!("mul", ops::mul, Mul, mul_derive, mul);
238create_derive!("mul", ops::mul, Div, div_derive, div);
239create_derive!("mul", ops::mul, Rem, rem_derive, rem);
240create_derive!("mul", ops::mul, Shr, shr_derive, shr);
241create_derive!("mul", ops::mul, Shl, shl_derive, shl);
242
243create_derive!(
244    "mul_assign",
245    ops::mul_assign,
246    MulAssign,
247    mul_assign_derive,
248    mul_assign,
249);
250create_derive!(
251    "mul_assign",
252    ops::mul_assign,
253    DivAssign,
254    div_assign_derive,
255    div_assign,
256);
257create_derive!(
258    "mul_assign",
259    ops::mul_assign,
260    RemAssign,
261    rem_assign_derive,
262    rem_assign,
263);
264create_derive!(
265    "mul_assign",
266    ops::mul_assign,
267    ShrAssign,
268    shr_assign_derive,
269    shr_assign,
270);
271create_derive!(
272    "mul_assign",
273    ops::mul_assign,
274    ShlAssign,
275    shl_assign_derive,
276    shl_assign,
277);
278
279create_derive!("not", not_like, Not, not_derive);
280create_derive!("not", not_like, Neg, neg_derive);
281
282create_derive!("sum", sum_like, Sum, sum_derive);
283create_derive!("sum", sum_like, Product, product_derive);
284
285create_derive!("try_from", try_from, TryFrom, try_from_derive, try_from);
286
287create_derive!("try_into", try_into, TryInto, try_into_derive, try_into);
288
289create_derive!(
290    "try_unwrap",
291    try_unwrap,
292    TryUnwrap,
293    try_unwrap_derive,
294    try_unwrap,
295);
296
297create_derive!("unwrap", unwrap, Unwrap, unwrap_derive, unwrap);