]> git.proxmox.com Git - rustc.git/blob - vendor/derive_more/src/lib.rs
New upstream version 1.67.1+dfsg1
[rustc.git] / vendor / derive_more / src / lib.rs
1 //! # `derive_more`
2 //!
3 //! [![Build Status](https://github.com/JelteF/derive_more/workflows/CI/badge.svg)](https://github.com/JelteF/derive_more/actions)
4 //! [![Latest Version](https://img.shields.io/crates/v/derive_more.svg)](https://crates.io/crates/derive_more)
5 //! [![Rust Documentation](https://img.shields.io/badge/api-rustdoc-blue.svg)](https://jeltef.github.io/derive_more/derive_more/)
6 //! [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/JelteF/derive_more/master/LICENSE)
7 //! [![Rust 1.36+](https://img.shields.io/badge/rustc-1.36+-lightgray.svg)](https://blog.rust-lang.org/2019/07/04/Rust-1.36.0.html)
8 //!
9 //! Rust has lots of builtin traits that are implemented for its basic types, such
10 //! as `Add`, `Not`, `From` or `Display`.
11 //! However, when wrapping these types inside your own structs or enums you lose the
12 //! implementations of these traits and are required to recreate them.
13 //! This is especially annoying when your own structures are very simple, such as
14 //! when using the commonly advised newtype pattern (e.g. `MyInt(i32)`).
15 //!
16 //! This library tries to remove these annoyances and the corresponding boilerplate code.
17 //! It does this by allowing you to derive lots of commonly used traits for both structs and enums.
18 //!
19 //! ## Example code
20 //!
21 //! By using this library the following code just works:
22 //!
23 //! ```rust
24 //! extern crate derive_more;
25 //! use derive_more::{Add, Display, From, Into};
26 //!
27 //! #[derive(PartialEq, From, Add)]
28 //! struct MyInt(i32);
29 //!
30 //! #[derive(PartialEq, From, Into)]
31 //! struct Point2D {
32 //! x: i32,
33 //! y: i32,
34 //! }
35 //!
36 //! #[derive(PartialEq, From, Add, Display)]
37 //! enum MyEnum {
38 //! #[display(fmt = "int: {}", _0)]
39 //! Int(i32),
40 //! Uint(u32),
41 //! #[display(fmt = "nothing")]
42 //! Nothing,
43 //! }
44 //!
45 //! assert!(MyInt(11) == MyInt(5) + 6.into());
46 //! assert!((5, 6) == Point2D { x: 5, y: 6 }.into());
47 //! assert!(MyEnum::Int(15) == (MyEnum::Int(8) + 7.into()).unwrap());
48 //! assert!(MyEnum::Int(15).to_string() == "int: 15");
49 //! assert!(MyEnum::Uint(42).to_string() == "42");
50 //! assert!(MyEnum::Nothing.to_string() == "nothing");
51 //! ```
52 //!
53 //! ## The derivable traits
54 //!
55 //! Below are all the traits that you can derive using this library.
56 //! Some trait derivations are so similar that the further documentation will only show a single one
57 //! of them.
58 //! You can recognize these by the "-like" suffix in their name.
59 //! The trait name before that will be the only one that is used throughout the further
60 //! documentation.
61 //!
62 //! It is important to understand what code gets generated when using one of the
63 //! derives from this crate.
64 //! That is why the links below explain what code gets generated for a trait for
65 //! each group from before.
66 //!
67 //! You can use the [`cargo-expand`] utility to see the exact code that is generated
68 //! for your specific type.
69 //! This will show you your code with all macros and derives expanded.
70 //!
71 //! **NOTE**: You still have to derive each trait separately. So `#[derive(Mul)]` doesn't
72 //! automatically derive `Div` as well. To derive both you should do `#[derive(Mul, Div)]`
73 //!
74 //! ### Conversion traits
75 //!
76 //! These are traits that are used to convert automatically between types.
77 //!
78 //! 1. [`From`]
79 //! 2. [`Into`]
80 //! 3. [`FromStr`]
81 //! 4. [`TryInto`]
82 //! 5. [`IntoIterator`]
83 //! 6. [`AsRef`]
84 //! 7. [`AsMut`]
85 //!
86 //! ### Formatting traits
87 //!
88 //! These traits are used for converting a struct to a string in different ways.
89 //!
90 //! 1. [`Display`-like], contains `Display`, `Binary`, `Octal`, `LowerHex`,
91 //! `UpperHex`, `LowerExp`, `UpperExp`, `Pointer`
92 //!
93 //! ### Error-handling traits
94 //! These traits are used to define error-types.
95 //!
96 //! 1. [`Error`]
97 //!
98 //! ### Operators
99 //!
100 //! These are traits that can be used for operator overloading.
101 //!
102 //! 1. [`Index`]
103 //! 2. [`Deref`]
104 //! 3. [`Not`-like], contains `Not` and `Neg`
105 //! 4. [`Add`-like], contains `Add`, `Sub`, `BitAnd`, `BitOr`, `BitXor`
106 //! 5. [`Mul`-like], contains `Mul`, `Div`, `Rem`, `Shr` and `Shl`
107 //! 3. [`Sum`-like], contains `Sum` and `Product`
108 //! 6. [`IndexMut`]
109 //! 7. [`DerefMut`]
110 //! 8. [`AddAssign`-like], contains `AddAssign`, `SubAssign`, `BitAndAssign`,
111 //! `BitOrAssign` and `BitXorAssign`
112 //! 9. [`MulAssign`-like], contains `MulAssign`, `DivAssign`, `RemAssign`,
113 //! `ShrAssign` and `ShlAssign`
114 //!
115 //! ### Static methods
116 //!
117 //! These don't derive traits, but derive static methods instead.
118 //!
119 //! 1. [`Constructor`], this derives a `new` method that can be used as a constructor.
120 //! This is very basic if you need more customization for your constructor, check
121 //! out the [`derive-new`] crate.
122 //! 2. [`IsVariant`], for each variant `foo` of an enum type, derives a `is_foo` method.
123 //! 3. [`Unwrap`], for each variant `foo` of an enum type, derives an `unwrap_foo` method.
124 //!
125 //! ## Generated code
126 //!
127 //! ## Installation
128 //!
129 //! This library requires Rust 1.36 or higher and it supports `no_std` out of the box.
130 //! Then add the following to `Cargo.toml`:
131 //!
132 //! ```toml
133 //! [dependencies]
134 //! derive_more = "0.99.0"
135 //! # You can specifiy the types of derives that you need for less time spent
136 //! # compiling. For the full list of features see this crate its Cargo.toml.
137 //! default-features = false
138 //! features = ["from", "add", "iterator"]
139 //! ```
140 //!
141 //! And this to the top of your Rust file for Rust 2018:
142 //!
143 //! ```rust
144 //! extern crate derive_more;
145 //! // use the derives that you want in the file
146 //! use derive_more::{Add, Display, From};
147 //! ```
148 //! If you're still using Rust 2015 you should add this instead:
149 //! ```rust
150 //! extern crate core;
151 //! #[macro_use]
152 //! extern crate derive_more;
153 //! # fn main(){}
154 //! ```
155 //!
156 //! [`cargo-expand`]: https://github.com/dtolnay/cargo-expand
157 //! [`derive-new`]: https://github.com/nrc/derive-new
158 //!
159 //! [`From`]: https://jeltef.github.io/derive_more/derive_more/from.html
160 //! [`Into`]: https://jeltef.github.io/derive_more/derive_more/into.html
161 //! [`FromStr`]: https://jeltef.github.io/derive_more/derive_more/from_str.html
162 //! [`TryInto`]: https://jeltef.github.io/derive_more/derive_more/try_into.html
163 //! [`IntoIterator`]: https://jeltef.github.io/derive_more/derive_more/into_iterator.html
164 //! [`AsRef`]: https://jeltef.github.io/derive_more/derive_more/as_ref.html
165 //! [`AsMut`]: https://jeltef.github.io/derive_more/derive_more/as_mut.html
166 //!
167 //! [`Display`-like]: https://jeltef.github.io/derive_more/derive_more/display.html
168 //!
169 //! [`Error`]: https://jeltef.github.io/derive_more/derive_more/error.html
170 //!
171 //! [`Index`]: https://jeltef.github.io/derive_more/derive_more/index_op.html
172 //! [`Deref`]: https://jeltef.github.io/derive_more/derive_more/deref.html
173 //! [`Not`-like]: https://jeltef.github.io/derive_more/derive_more/not.html
174 //! [`Add`-like]: https://jeltef.github.io/derive_more/derive_more/add.html
175 //! [`Mul`-like]: https://jeltef.github.io/derive_more/derive_more/mul.html
176 //! [`Sum`-like]: https://jeltef.github.io/derive_more/derive_more/sum.html
177 //! [`IndexMut`]: https://jeltef.github.io/derive_more/derive_more/index_mut.html
178 //! [`DerefMut`]: https://jeltef.github.io/derive_more/derive_more/deref_mut.html
179 //! [`AddAssign`-like]: https://jeltef.github.io/derive_more/derive_more/add_assign.html
180 //! [`MulAssign`-like]: https://jeltef.github.io/derive_more/derive_more/mul_assign.html
181 //!
182 //! [`Constructor`]: https://jeltef.github.io/derive_more/derive_more/constructor.html
183 //! [`IsVariant`]: https://jeltef.github.io/derive_more/derive_more/is_variant.html
184 //! [`Unwrap`]: https://jeltef.github.io/derive_more/derive_more/unwrap.html
185
186 #![recursion_limit = "128"]
187
188 extern crate proc_macro;
189
190 use proc_macro::TokenStream;
191 use syn::parse::Error as ParseError;
192
193 mod utils;
194
195 #[cfg(any(feature = "add_assign", feature = "mul_assign"))]
196 mod add_assign_like;
197 #[cfg(any(
198 feature = "add",
199 feature = "add_assign",
200 feature = "mul",
201 feature = "mul_assign",
202 ))]
203 mod add_helpers;
204 #[cfg(any(feature = "add", feature = "mul"))]
205 mod add_like;
206 #[cfg(feature = "as_mut")]
207 mod as_mut;
208 #[cfg(feature = "as_ref")]
209 mod as_ref;
210 #[cfg(feature = "constructor")]
211 mod constructor;
212 #[cfg(feature = "deref")]
213 mod deref;
214 #[cfg(feature = "deref_mut")]
215 mod deref_mut;
216 #[cfg(feature = "display")]
217 mod display;
218 #[cfg(feature = "error")]
219 mod error;
220 #[cfg(feature = "from")]
221 mod from;
222 #[cfg(feature = "from_str")]
223 mod from_str;
224 #[cfg(feature = "index")]
225 mod index;
226 #[cfg(feature = "index_mut")]
227 mod index_mut;
228 #[cfg(feature = "into")]
229 mod into;
230 #[cfg(feature = "into_iterator")]
231 mod into_iterator;
232 #[cfg(feature = "is_variant")]
233 mod is_variant;
234 #[cfg(feature = "mul_assign")]
235 mod mul_assign_like;
236 #[cfg(any(feature = "mul", feature = "mul_assign"))]
237 mod mul_helpers;
238 #[cfg(feature = "mul")]
239 mod mul_like;
240 #[cfg(feature = "not")]
241 mod not_like;
242 #[cfg(feature = "display")]
243 #[allow(ellipsis_inclusive_range_patterns)]
244 #[allow(clippy::all)]
245 mod parsing;
246 #[cfg(feature = "sum")]
247 mod sum_like;
248 #[cfg(feature = "try_into")]
249 mod try_into;
250 #[cfg(feature = "unwrap")]
251 mod unwrap;
252
253 // This trait describes the possible return types of
254 // the derives. A derive can generally be infallible and
255 // return a TokenStream, or it can be fallible and return
256 // a Result<TokenStream, syn::parse::Error>.
257 trait Output {
258 fn process(self) -> TokenStream;
259 }
260
261 impl Output for proc_macro2::TokenStream {
262 fn process(self) -> TokenStream {
263 self.into()
264 }
265 }
266
267 impl Output for Result<proc_macro2::TokenStream, ParseError> {
268 fn process(self) -> TokenStream {
269 match self {
270 Ok(ts) => ts.into(),
271 Err(e) => e.to_compile_error().into(),
272 }
273 }
274 }
275
276 macro_rules! create_derive(
277 ($feature:literal, $mod_:ident, $trait_:ident, $fn_name: ident $(,$attribute:ident)* $(,)?) => {
278 #[cfg(feature = $feature)]
279 #[proc_macro_derive($trait_, attributes($($attribute),*))]
280 #[doc(hidden)]
281 pub fn $fn_name(input: TokenStream) -> TokenStream {
282 let ast = syn::parse(input).unwrap();
283 Output::process($mod_::expand(&ast, stringify!($trait_)))
284 }
285 }
286 );
287
288 create_derive!("from", from, From, from_derive, from);
289
290 create_derive!("into", into, Into, into_derive, into);
291
292 create_derive!("constructor", constructor, Constructor, constructor_derive);
293
294 create_derive!("not", not_like, Not, not_derive);
295 create_derive!("not", not_like, Neg, neg_derive);
296
297 create_derive!("add", add_like, Add, add_derive);
298 create_derive!("add", add_like, Sub, sub_derive);
299 create_derive!("add", add_like, BitAnd, bit_and_derive);
300 create_derive!("add", add_like, BitOr, bit_or_derive);
301 create_derive!("add", add_like, BitXor, bit_xor_derive);
302
303 create_derive!("mul", mul_like, Mul, mul_derive, mul);
304 create_derive!("mul", mul_like, Div, div_derive, div);
305 create_derive!("mul", mul_like, Rem, rem_derive, rem);
306 create_derive!("mul", mul_like, Shr, shr_derive, shr);
307 create_derive!("mul", mul_like, Shl, shl_derive, shl);
308
309 create_derive!("add_assign", add_assign_like, AddAssign, add_assign_derive,);
310 create_derive!("add_assign", add_assign_like, SubAssign, sub_assign_derive,);
311 create_derive!(
312 "add_assign",
313 add_assign_like,
314 BitAndAssign,
315 bit_and_assign_derive,
316 );
317 create_derive!(
318 "add_assign",
319 add_assign_like,
320 BitOrAssign,
321 bit_or_assign_derive,
322 );
323 create_derive!(
324 "add_assign",
325 add_assign_like,
326 BitXorAssign,
327 bit_xor_assign_derive,
328 );
329
330 create_derive!(
331 "mul_assign",
332 mul_assign_like,
333 MulAssign,
334 mul_assign_derive,
335 mul_assign,
336 );
337 create_derive!(
338 "mul_assign",
339 mul_assign_like,
340 DivAssign,
341 div_assign_derive,
342 div_assign,
343 );
344 create_derive!(
345 "mul_assign",
346 mul_assign_like,
347 RemAssign,
348 rem_assign_derive,
349 rem_assign,
350 );
351 create_derive!(
352 "mul_assign",
353 mul_assign_like,
354 ShrAssign,
355 shr_assign_derive,
356 shr_assign,
357 );
358 create_derive!(
359 "mul_assign",
360 mul_assign_like,
361 ShlAssign,
362 shl_assign_derive,
363 shl_assign,
364 );
365
366 create_derive!("sum", sum_like, Sum, sum_derive);
367 create_derive!("sum", sum_like, Product, product_derive);
368
369 create_derive!("error", error, Error, error_derive, error);
370
371 create_derive!("from_str", from_str, FromStr, from_str_derive);
372
373 create_derive!("display", display, Display, display_derive, display);
374 create_derive!("display", display, Binary, binary_derive, binary);
375 create_derive!("display", display, Octal, octal_derive, octal);
376 create_derive!("display", display, LowerHex, lower_hex_derive, lower_hex);
377 create_derive!("display", display, UpperHex, upper_hex_derive, upper_hex);
378 create_derive!("display", display, LowerExp, lower_exp_derive, lower_exp);
379 create_derive!("display", display, UpperExp, upper_exp_derive, upper_exp);
380 create_derive!("display", display, Pointer, pointer_derive, pointer);
381 create_derive!("display", display, DebugCustom, debug_custom_derive, debug);
382
383 create_derive!("index", index, Index, index_derive, index);
384 create_derive!(
385 "index_mut",
386 index_mut,
387 IndexMut,
388 index_mut_derive,
389 index_mut,
390 );
391
392 create_derive!(
393 "into_iterator",
394 into_iterator,
395 IntoIterator,
396 into_iterator_derive,
397 into_iterator,
398 );
399
400 create_derive!("try_into", try_into, TryInto, try_into_derive, try_into);
401
402 create_derive!("deref", deref, Deref, deref_derive, deref);
403 create_derive!(
404 "deref_mut",
405 deref_mut,
406 DerefMut,
407 deref_mut_derive,
408 deref_mut,
409 );
410
411 create_derive!("as_ref", as_ref, AsRef, as_ref_derive, as_ref);
412 create_derive!("as_mut", as_mut, AsMut, as_mut_derive, as_mut);
413
414 create_derive!(
415 "is_variant",
416 is_variant,
417 IsVariant,
418 is_variant_derive,
419 is_variant
420 );
421
422 create_derive!("unwrap", unwrap, Unwrap, unwrap_derive, unwrap);