]>
git.proxmox.com Git - rustc.git/blob - vendor/derive_more/src/lib.rs
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)
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)`).
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.
21 //! By using this library the following code just works:
24 //! extern crate derive_more;
25 //! use derive_more::{Add, Display, From, Into};
27 //! #[derive(PartialEq, From, Add)]
28 //! struct MyInt(i32);
30 //! #[derive(PartialEq, From, Into)]
36 //! #[derive(PartialEq, From, Add, Display)]
38 //! #[display(fmt = "int: {}", _0)]
41 //! #[display(fmt = "nothing")]
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");
53 //! ## The derivable traits
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
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
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.
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.
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)]`
74 //! ### Conversion traits
76 //! These are traits that are used to convert automatically between types.
82 //! 5. [`IntoIterator`]
86 //! ### Formatting traits
88 //! These traits are used for converting a struct to a string in different ways.
90 //! 1. [`Display`-like], contains `Display`, `Binary`, `Octal`, `LowerHex`,
91 //! `UpperHex`, `LowerExp`, `UpperExp`, `Pointer`
93 //! ### Error-handling traits
94 //! These traits are used to define error-types.
100 //! These are traits that can be used for operator overloading.
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`
110 //! 8. [`AddAssign`-like], contains `AddAssign`, `SubAssign`, `BitAndAssign`,
111 //! `BitOrAssign` and `BitXorAssign`
112 //! 9. [`MulAssign`-like], contains `MulAssign`, `DivAssign`, `RemAssign`,
113 //! `ShrAssign` and `ShlAssign`
115 //! ### Static methods
117 //! These don't derive traits, but derive static methods instead.
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.
125 //! ## Generated code
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`:
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"]
141 //! And this to the top of your Rust file for Rust 2018:
144 //! extern crate derive_more;
145 //! // use the derives that you want in the file
146 //! use derive_more::{Add, Display, From};
148 //! If you're still using Rust 2015 you should add this instead:
150 //! extern crate core;
152 //! extern crate derive_more;
156 //! [`cargo-expand`]: https://github.com/dtolnay/cargo-expand
157 //! [`derive-new`]: https://github.com/nrc/derive-new
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
167 //! [`Display`-like]: https://jeltef.github.io/derive_more/derive_more/display.html
169 //! [`Error`]: https://jeltef.github.io/derive_more/derive_more/error.html
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
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
186 #![recursion_limit = "128"]
188 extern crate proc_macro
;
190 use proc_macro
::TokenStream
;
191 use syn
::parse
::Error
as ParseError
;
195 #[cfg(any(feature = "add_assign", feature = "mul_assign"))]
199 feature
= "add_assign",
201 feature
= "mul_assign",
204 #[cfg(any(feature = "add", feature = "mul"))]
206 #[cfg(feature = "as_mut")]
208 #[cfg(feature = "as_ref")]
210 #[cfg(feature = "constructor")]
212 #[cfg(feature = "deref")]
214 #[cfg(feature = "deref_mut")]
216 #[cfg(feature = "display")]
218 #[cfg(feature = "error")]
220 #[cfg(feature = "from")]
222 #[cfg(feature = "from_str")]
224 #[cfg(feature = "index")]
226 #[cfg(feature = "index_mut")]
228 #[cfg(feature = "into")]
230 #[cfg(feature = "into_iterator")]
232 #[cfg(feature = "is_variant")]
234 #[cfg(feature = "mul_assign")]
236 #[cfg(any(feature = "mul", feature = "mul_assign"))]
238 #[cfg(feature = "mul")]
240 #[cfg(feature = "not")]
242 #[cfg(feature = "display")]
243 #[allow(ellipsis_inclusive_range_patterns)]
244 #[allow(clippy::all)]
246 #[cfg(feature = "sum")]
248 #[cfg(feature = "try_into")]
250 #[cfg(feature = "unwrap")]
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>.
258 fn process(self) -> TokenStream
;
261 impl Output
for proc_macro2
::TokenStream
{
262 fn process(self) -> TokenStream
{
267 impl Output
for Result
<proc_macro2
::TokenStream
, ParseError
> {
268 fn process(self) -> TokenStream
{
271 Err(e
) => e
.to_compile_error().into(),
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),*))]
281 pub fn $
fn_name(input
: TokenStream
) -> TokenStream
{
282 let ast
= syn
::parse(input
).unwrap();
283 Output
::process($mod_
::expand(&ast
, stringify
!($trait_
)))
288 create_derive
!("from", from
, From
, from_derive
, from
);
290 create_derive
!("into", into
, Into
, into_derive
, into
);
292 create_derive
!("constructor", constructor
, Constructor
, constructor_derive
);
294 create_derive
!("not", not_like
, Not
, not_derive
);
295 create_derive
!("not", not_like
, Neg
, neg_derive
);
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
);
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
);
309 create_derive
!("add_assign", add_assign_like
, AddAssign
, add_assign_derive
,);
310 create_derive
!("add_assign", add_assign_like
, SubAssign
, sub_assign_derive
,);
315 bit_and_assign_derive
,
321 bit_or_assign_derive
,
327 bit_xor_assign_derive
,
366 create_derive
!("sum", sum_like
, Sum
, sum_derive
);
367 create_derive
!("sum", sum_like
, Product
, product_derive
);
369 create_derive
!("error", error
, Error
, error_derive
, error
);
371 create_derive
!("from_str", from_str
, FromStr
, from_str_derive
);
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
);
383 create_derive
!("index", index
, Index
, index_derive
, index
);
396 into_iterator_derive
,
400 create_derive
!("try_into", try_into
, TryInto
, try_into_derive
, try_into
);
402 create_derive
!("deref", deref
, Deref
, deref_derive
, deref
);
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
);
422 create_derive
!("unwrap", unwrap
, Unwrap
, unwrap_derive
, unwrap
);