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