derive_ex/lib.rs
1#![allow(clippy::large_enum_variant)]
2
3extern crate proc_macro;
4
5#[macro_use]
6mod syn_utils;
7
8mod bound;
9mod common;
10mod item_impl;
11mod item_type;
12
13use proc_macro2::TokenStream;
14use quote::quote;
15use syn::{parse2, Item, Result};
16
17// #[include_doc("../../doc/derive_ex.md", start)]
18/// Improved version of the macro to implement the traits defined in the standard library.
19///
20/// - [Attributes](#attributes)
21/// - [Derive `Copy`](#derive-copy)
22/// - [Derive `Clone`](#derive-clone)
23/// - [Derive `Debug`](#derive-debug)
24/// - [`#[debug(ignore)]`](#debugignore)
25/// - [`#[debug(transparent)]`](#debugtransparent)
26/// - [`#[debug(bound(...))]`](#debugbound)
27/// - [Derive `Default`](#derive-default)
28/// - [Derive `Ord`, `PartialOrd`, `Eq`, `PartialEq`, `Hash`](#derive-ord-partialord-eq-partialeq-hash)
29/// - [`#[ord(ignore)]`](#ordignore)
30/// - [`#[ord(reverse)]`](#ordreverse)
31/// - [`#[ord(by = ...)]`](#ordby--)
32/// - [`#[ord(key = ...)]`](#ordkey--)
33/// - [`#[ord(bound(...))]`](#ordbound)
34/// - [Derive `Deref`](#derive-deref)
35/// - [Derive `DerefMut`](#derive-derefmut)
36/// - [Derive operators](#derive-operators)
37/// - [`Add`-like](#add-like)
38/// - [Derive `Add` from struct definition](#derive-add-from-struct-definition)
39/// - [Derive `Add` from `impl Add`](#derive-add-from-impl-add)
40/// - [Derive `Add` from `impl AddAssign`](#derive-add-from-impl-addassign)
41/// - [`AddAssign`-like](#addassign-like)
42/// - [Derive `AddAssign` from struct definition](#derive-addassign-from-struct-definition)
43/// - [Derive `AddAssign` from `impl Add`](#derive-addassign-from-impl-add)
44/// - [Derive both `Add` and `AddAssign` from `impl Add`](#derive-both-add-and-addassign-from-impl-add)
45/// - [`Not`-like](#not-like)
46/// - [Specify trait bound](#specify-trait-bound)
47/// - [`#[bound(T)]`](#boundt)
48/// - [`#[bound(T : TraitName)]`](#boundt--traitname)
49/// - [`#[bound(..)]`](#bound)
50/// - [`#[bound()]`](#bound-1)
51/// - [Display generated code](#display-generated-code)
52///
53/// # Attributes
54///
55/// You can write attributes in the following positions.
56///
57/// | attribute | impl | struct | enum | variant | field |
58/// | -------------------------- | ---- | ------ | ---- | ------- | ----- |
59/// | `#[derive_ex(Copy)]` | | ✔ | ✔ | ✔ | ✔ |
60/// | `#[derive_ex(Clone)]` | | ✔ | ✔ | ✔ | ✔ |
61/// | `#[derive_ex(Debug)]` | | ✔ | ✔ | ✔ | ✔ |
62/// | `#[derive_ex(Default)]` | | ✔ | ✔ | ✔ | ✔ |
63/// | `#[derive_ex(Ord)]` | | ✔ | ✔ | ✔ | ✔ |
64/// | `#[derive_ex(Deref)]` | | ✔ | | | |
65/// | `#[derive_ex(DerefMut)]` | | ✔ | | | |
66/// | `#[derive_ex(Add)]` | ✔ | ✔ | | | ✔ |
67/// | `#[derive_ex(AddAssign)]` | ✔ | ✔ | | | ✔ |
68/// | `#[derive_ex(Not)]` | | ✔ | ✔ | ✔ | ✔ |
69/// | `#[derive_ex(bound(...))]` | | ✔ | ✔ | ✔ | ✔ |
70/// | `#[derive_ex(dump))]` | ✔ | ✔ | ✔ | | |
71/// | `#[default]` | | ✔ | ✔ | ✔ | ✔ |
72/// | `#[debug]` | | ✔ | ✔ | ✔ | ✔ |
73/// | `#[ord]` | | ✔ | ✔ | ✔ | ✔ |
74///
75/// # Derive `Copy`
76///
77/// You can use `#[derive_ex(Copy)]` to implement [`Copy`].
78///
79/// ```rust
80/// use derive_ex::derive_ex;
81/// use std::marker::PhantomData;
82///
83/// #[derive_ex(Copy, Clone)]
84/// struct X<T>(PhantomData<T>);
85/// ```
86///
87/// The standard `#[derive(Copy)]` sets `Copy` constraint on the generic parameters, while `#[derive_ex(Copy)]` sets `Copy` constraint on the type of field containing generic parameters.
88///
89/// For example, adding `#[derive(Copy)]` to the previous structure `X<T>` generates the following code.
90///
91/// Since `where T: Copy` is specified, if `T` does not implement `DebugCopy`, then `X<T>` does not implement `Copy`.
92///
93/// ```rust
94/// # use std::marker::PhantomData;
95/// # #[derive(Clone)]
96/// # struct X<T>(PhantomData<T>);
97/// use core::marker::Copy;
98/// impl<T: Copy> Copy for X<T>
99/// where
100/// T : Copy
101/// {
102/// }
103/// ```
104///
105/// On the other hand, `#[derive_ex(Copy)]` generates the following code.
106///
107/// Unlike the standard `#[derive(Copy)]`, `X<T>` always implements `Copy`.
108///
109/// ```rust
110/// # use derive_ex::derive_ex;
111/// # use std::marker::PhantomData;
112/// # #[derive_ex(Clone)]
113/// # struct X<T>(PhantomData<T>);
114/// use core::marker::Copy;
115/// impl<T: Copy> Copy for X<T>
116/// where
117/// PhantomData<T>: Copy,
118/// {
119/// }
120/// ```
121///
122/// # Derive `Clone`
123///
124/// You can use `#[derive_ex(Clone)]` to implement [`Clone`].
125///
126/// ```rust
127/// use derive_ex::derive_ex;
128///
129/// #[derive_ex(Clone)]
130/// struct X(String);
131///
132/// #[derive_ex(Clone)]
133/// enum Y {
134/// X,
135/// B,
136/// }
137/// ```
138///
139/// It has the following differences from the standard `#[derive(Clone)]`.
140///
141/// - Generates [`Clone::clone_from`].
142/// - The standard `#[derive(Clone)]` sets `Clone` constraint on the generic parameters, while `#[derive_ex(Clone)]` sets `Clone` constraint on the type of field containing generic parameters.
143///
144/// For example, to derive `Clone` for the following type
145///
146/// ```rust
147/// use std::rc::Rc;
148/// struct X<T> {
149/// a: Rc<T>,
150/// b: String,
151/// }
152/// ```
153///
154/// The standard `#[derive(Clone)]` generates the following code.
155///
156/// Since `where T: Clone` is specified, if `T` does not implement `Clone`, then `X<T>` does not implement `Clone`.
157///
158/// ```rust
159/// # use std::rc::Rc;
160/// # struct X<T> {
161/// # a: Rc<T>,
162/// # b: String,
163/// # }
164/// impl<T> Clone for X<T>
165/// where
166/// T: Clone,
167/// {
168/// fn clone(&self) -> Self {
169/// X {
170/// a: self.a.clone(),
171/// b: self.b.clone(),
172/// }
173/// }
174/// }
175/// ```
176///
177/// On the other hand, `#[derive_ex(Clone)]` generates the following code.
178///
179/// Unlike the standard `#[derive(Clone)]`, `X<T>` always implements `Clone`.
180///
181/// ```rust
182/// # use std::rc::Rc;
183/// # struct X<T> {
184/// # a: Rc<T>,
185/// # b: String,
186/// # }
187/// impl<T> Clone for X<T>
188/// where
189/// Rc<T>: Clone,
190/// {
191/// fn clone(&self) -> Self {
192/// X {
193/// a: self.a.clone(),
194/// b: self.b.clone(),
195/// }
196/// }
197/// fn clone_from(&mut self, source: &Self) {
198/// self.a.clone_from(&source.a);
199/// self.b.clone_from(&source.b);
200/// }
201/// }
202/// ```
203///
204/// If you want to remove `where Rc<T>: Clone` in the above example, you can use `#[derive(Clone(bound()))]`.
205/// See [Specify trait bound](#specify-trait-bound) for details.
206///
207/// # Derive `Debug`
208///
209/// You can use `#[derive_ex(Debug)]` to implement [`Debug`].
210///
211/// The following helper attribute arguments allow you to customize your `Debug` implementation.
212///
213/// | attribute | struct | enum | variant | field |
214/// | ---------------------------------- | ------ | ---- | ------- | ----- |
215/// | [`ignore`](#debugignore) | | | | ✔ |
216/// | [`transparent`](#debugtransparent) | | | | ✔ |
217/// | [`bound(...)`](#debugbound) | ✔ | ✔ | ✔ | ✔ |
218///
219/// ## `#[debug(ignore)]`
220///
221/// By setting `#[debug(ignore)]` to a field, you can exclude that field from debug output.
222///
223/// ```rust
224/// use derive_ex::derive_ex;
225/// #[derive_ex(Debug)]
226/// struct X {
227/// a: u32,
228/// #[debug(ignore)]
229/// b: u32,
230/// }
231/// assert_eq!(format!("{:?}", X { a: 1, b: 2 }), "X { a: 1 }");
232/// ```
233///
234/// ## `#[debug(transparent)]`
235///
236/// You can transfer processing to a field by setting `#[debug(transparent)]` to that field.
237///
238/// ```rust
239/// use derive_ex::derive_ex;
240/// #[derive_ex(Debug)]
241/// struct X {
242/// a: u32,
243/// #[debug(transparent)]
244/// b: u32,
245/// }
246/// assert_eq!(format!("{:?}", X { a: 1, b: 2 }), "2");
247/// ```
248///
249/// ## `#[debug(bound(...))]`
250///
251/// The standard `#[derive(Debug)]` sets `Debug` constraint on the generic parameters, while `#[derive_ex(Debug)]` sets `Debug` constraint on the type of field containing generic parameters.
252///
253/// For example, to derive `Debug` for the following type
254///
255/// ```rust
256/// use std::marker::PhantomData;
257/// struct X<T>(PhantomData<T>);
258/// ```
259///
260/// The standard `#[derive(Debug)]` generates the following code.
261///
262/// Since `where T: Debug` is specified, if `T` does not implement `Debug`, then `X<T>` does not implement `Debug`.
263///
264/// ```rust
265/// # use std::marker::PhantomData;
266/// # struct X<T>(PhantomData<T>);
267/// use std::fmt::Debug;
268/// impl<T> Debug for X<T>
269/// where
270/// T: Debug,
271/// {
272/// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
273/// f.debug_struct("X").finish()
274/// }
275/// }
276/// ```
277///
278/// On the other hand, `#[derive_ex(Debug)]` generates the following code.
279///
280/// Unlike the standard `#[derive(Debug)]`, `X<T>` always implements `Debug`.
281///
282/// ```rust
283/// # use std::marker::PhantomData;
284/// # struct X<T>(PhantomData<T>);
285/// use std::fmt::Debug;
286/// impl<T> Debug for X<T>
287/// where
288/// PhantomData<T>: Debug,
289/// {
290/// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
291/// f.debug_struct("X").finish()
292/// }
293/// }
294/// ```
295///
296/// You can also manually specify a trait bound. See [Specify trait bound](#specify-trait-bound) for details.
297///
298/// # Derive `Default`
299///
300/// You can use `#[derive_ex(Default)]` to implement [`Default`].
301///
302/// ```rust
303/// use derive_ex::derive_ex;
304/// #[derive_ex(Default)]
305/// struct X {
306/// a: u8,
307/// }
308/// let x = X::default();
309/// assert_eq!(x.a, 0);
310/// ```
311///
312/// You can use `#[default(...)]` with struct or enum to set the default value.
313///
314/// ```rust
315/// use derive_ex::derive_ex;
316/// #[derive_ex(Default)]
317/// #[default(X::new())]
318/// struct X(u8);
319///
320/// impl X {
321/// fn new() -> Self {
322/// X(5)
323/// }
324/// }
325///
326/// let x = X::default();
327/// assert_eq!(x.0, 5);
328/// ```
329///
330/// You can use `#[default(...)]` with a field to set the field's default value.
331///
332/// ```rust
333/// use derive_ex::derive_ex;
334/// #[derive_ex(Default)]
335/// struct X {
336/// #[default(5)]
337/// a: u8,
338/// }
339///
340/// let x = X::default();
341/// assert_eq!(x.a, 5);
342/// ```
343///
344/// You can use `#[default]` to set the default variant.
345///
346/// ```rust
347/// use derive_ex::derive_ex;
348/// #[derive(Debug, Eq, PartialEq)]
349/// #[derive_ex(Default)]
350/// enum X {
351/// A,
352/// #[default]
353/// B,
354/// }
355/// assert_eq!(X::default(), X::B);
356/// ```
357///
358/// If a string literal or a single path is specified in `#[default(...)]`, conversion by `Into` is performed.
359///
360/// ```rust
361/// use derive_ex::derive_ex;
362///
363/// #[derive(Debug, PartialEq)]
364/// #[derive_ex(Default)]
365/// struct X(#[default("abc")]String);
366/// assert_eq!(X::default(), X("abc".into()));
367///
368/// const S: &str = "xyz";
369/// #[derive(Debug, PartialEq)]
370/// #[derive_ex(Default)]
371/// struct Y(#[default(S)]String);
372/// assert_eq!(Y::default(), Y(S.into()));
373/// ```
374///
375/// The standard `#[derive(Default)]` sets `Default` constraint on the generic parameters, while `#[derive_ex(Default)]` sets `Default` constraint on the type of field containing generic parameters.
376///
377/// For example, to derive `Default` for the following type
378///
379/// ```rust
380/// struct X<T>(Option<T>);
381/// ```
382///
383/// The standard `#[derive(Default)]` generates the following code.
384///
385/// Since `where T: Default` is specified, if `T` does not implement `Default`, then `X<T>` does not implement `Default`.
386///
387/// ```rust
388/// # struct X<T>(Option<T>);
389/// impl<T> Default for X<T>
390/// where
391/// T: Default,
392/// {
393/// fn default() -> Self {
394/// X(<Option<T>>::default())
395/// }
396/// }
397/// ```
398///
399/// On the other hand, `#[derive_ex(Default)]` generates the following code.
400///
401/// Unlike the standard `#[derive(Default)]`, `X<T>` always implements `Default`.
402///
403/// ```rust
404/// # struct X<T>(Option<T>);
405/// impl<T> Default for X<T>
406/// where
407/// Option<T>: Default,
408/// {
409/// fn default() -> Self {
410/// X(<Option<T>>::default())
411/// }
412/// }
413/// ```
414///
415/// Field types with manually set default values are not used as type constraints.
416///
417/// In the following example, `where T : Default` is not generated.
418///
419/// ```rust
420/// use derive_ex::derive_ex;
421///
422/// #[derive(Eq, PartialEq, Debug)]
423/// struct NoDefault;
424/// trait New {
425/// fn new() -> Self;
426/// }
427/// impl New for NoDefault {
428/// fn new() -> Self {
429/// NoDefault
430/// }
431/// }
432///
433/// #[derive(Eq, PartialEq, Debug)]
434/// #[derive_ex(Default)]
435/// struct X<T: New> {
436/// #[default(T::new())]
437/// a: T,
438/// }
439/// assert_eq!(X::default(), X { a: NoDefault })
440/// ```
441///
442/// # Derive `Ord`, `PartialOrd`, `Eq`, `PartialEq`, `Hash`
443///
444/// `Ord`, `PartialOrd`, `Eq`, `PartialEq`, `Hash` can be derived using common settings.
445///
446/// To avoid repeating settings, one helper attribute affects multiple traits.
447///
448/// The table below shows which helper attributes affect which trait.
449///
450/// The helper attributes in the lines below are applied preferentially.
451///
452/// | attribute | `Ord` | `PartialOrd` | `Eq` | `PartialEq` | `Hash` |
453/// | --------------------- | ----- | ------------ | ---- | ----------- | ------ |
454/// | `#[ord(...)]` | ✔ | ✔ | ✔ | ✔ | ✔ |
455/// | `#[partial_ord(...)]` | | ✔ | | ✔ | |
456/// | `#[eq(...)]` | | | ✔ | ✔ | ✔ |
457/// | `#[partial_eq(...)]` | | | ✔ | ✔ | |
458/// | `#[hash(...)]` | | | | | ✔ |
459///
460/// The following table shows the helper attribute arguments and the locations where they can be used.
461///
462/// | argument | struct | enum | variant | field | `#[ord]` | `#[partial_ord]` | `#[eq]` | `#[partial_eq]` | `#[hash]` |
463/// | ------------------------- | ------ | ---- | ------- | ----- | -------- | ---------------- | ------- | --------------- | --------- |
464/// | [`ignore`](#ordignore) | | | | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
465/// | [`reverse`](#ordreverse) | | | | ✔ | ✔ | ✔ | | | |
466/// | [`by = ...`](#ordby--) | | | | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
467/// | [`key = ...`](#ordkey--) | | | | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
468/// | [`bound(...)`](#ordbound) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
469///
470/// If you modify the behavior of a specific trait by `by = ...` or `key = ...`, you must also modify the behavior of other traits by `by = ...` or `key = ...`.
471/// Trying to mix modified behavior with default behavior will result in a compilation error.
472///
473/// ## `#[ord(ignore)]`
474///
475/// Specifying `ignore` for a field excludes that field from comparison and hash calculation.
476///
477/// You cannot change whether `ignore` is applied by the trait.
478///
479/// A compile error occurs when trying to apply `ignore` to only some of the traits.
480///
481/// ```rust
482/// use derive_ex::derive_ex;
483///
484/// #[derive_ex(Eq, PartialEq, Debug)]
485/// struct X(#[eq(ignore)] u8);
486///
487/// assert_eq!(X(1), X(2));
488/// ```
489///
490/// ## `#[ord(reverse)]`
491///
492/// Specifying `reverse` for a field reverses the comparison order.
493///
494/// It can also be used together with `by = ...` or `key = ...`.
495///
496/// ```rust
497/// use derive_ex::derive_ex;
498///
499/// #[derive_ex(PartialOrd, PartialEq, Debug)]
500/// struct X(#[partial_ord(reverse)] u8);
501///
502/// assert!(X(1) > X(2));
503/// ```
504///
505/// ## `#[ord(by = ...)]`
506///
507/// You can set up a comparison method by specifying a function with the same signature as the trait's required method.
508///
509/// `#[hash(by = ...)]` only changes the behavior of `Hash`.
510///
511/// Other attributes act on attributes other than `Hash`.
512///
513/// ```rust
514/// use derive_ex::derive_ex;
515/// use std::cmp::Ordering;
516///
517/// #[derive_ex(Ord, PartialOrd, Eq, PartialEq, Debug)]
518/// struct X(#[ord(by = f64::total_cmp)] f64);
519///
520/// assert_eq!(X(1.0).cmp(&X(2.0)), Ordering::Less);
521/// ```
522///
523/// ## `#[ord(key = ...)]`
524///
525/// Delegates processing to the value of the specified expression.
526///
527/// In this expression, the field itself is represented by `$`.
528///
529/// ```rust
530/// use derive_ex::derive_ex;
531///
532/// #[derive_ex(Eq, PartialEq, Debug)]
533/// struct X(#[eq(key = $.len())] &'static str);
534///
535/// assert_eq!(X("a"), X("b"));
536/// assert_ne!(X("a"), X("aa"));
537/// ```
538///
539/// ## `#[ord(bound(...))]`
540///
541/// Specify the trait bounds.
542///
543/// If the default trait bounds are specified with a high-priority helper attribute, the trait bounds of a lower-priority helper attribute will be used.
544///
545/// If `by = ...` or `key = ...` is specified with a high-priority helper attribute, the trait bounds of a lower-priority helper attribute will not be used.
546///
547/// For details, see [Specify trait bound](#specify-trait-bound).
548///
549/// # Derive `Deref`
550///
551/// You can use `#[derive(Deref)]` for struct with a single field to implement `Deref`.
552///
553/// ```rust
554/// use derive_ex::derive_ex;
555///
556/// #[derive_ex(Deref)]
557/// struct X(u8);
558///
559/// let _: &u8 = &X(10u8);
560/// ```
561///
562/// # Derive `DerefMut`
563///
564/// You can use `#[derive(DerefMut)]` for struct with a single field to implement `DerefMut`.
565///
566/// ```rust
567/// use derive_ex::derive_ex;
568///
569/// #[derive_ex(Deref, DerefMut)]
570/// struct X(u8);
571///
572/// let _: &mut u8 = &mut X(10u8);
573/// ```
574///
575/// # Derive operators
576///
577/// ## `Add`-like
578///
579/// In this document, `Add` is used as an example, but all of the following traits can be used in the same way.
580///
581/// - `Add`
582/// - `BitAnd`
583/// - `BitOr`
584/// - `BitXor`
585/// - `Div`
586/// - `Mul`
587/// - `Rem`
588/// - `Shl`
589/// - `Shr`
590/// - `Sub`
591///
592/// ### Derive `Add` from struct definition
593///
594/// You can use `#[derive(Add)]` on struct definition to derive `Add`.
595///
596/// ```rust
597/// use derive_ex::derive_ex;
598/// #[derive_ex(Add)]
599/// struct X {
600/// a: u8,
601/// b: u32,
602/// }
603/// ```
604///
605/// The above code generates the following code.
606///
607/// ```rust
608/// # use ::core::ops::Add;
609/// # use derive_ex::derive_ex;
610/// # struct X {
611/// # a: u8,
612/// # b: u32,
613/// # }
614/// impl Add<X> for X {
615/// type Output = X;
616/// fn add(self, rhs: X) -> Self::Output {
617/// X {
618/// a: self.a + rhs.a,
619/// b: self.b + rhs.b,
620/// }
621/// }
622/// }
623/// impl Add<&X> for X {
624/// type Output = X;
625/// fn add(self, rhs: &X) -> Self::Output {
626/// X {
627/// a: self.a + &rhs.a,
628/// b: self.b + &rhs.b,
629/// }
630/// }
631/// }
632/// impl Add<X> for &X {
633/// type Output = X;
634/// fn add(self, rhs: X) -> Self::Output {
635/// X {
636/// a: &self.a + rhs.a,
637/// b: &self.b + rhs.b,
638/// }
639/// }
640/// }
641/// impl Add<&X> for &X {
642/// type Output = X;
643/// fn add(self, rhs: &X) -> Self::Output {
644/// X {
645/// a: &self.a + &rhs.a,
646/// b: &self.b + &rhs.b,
647/// }
648/// }
649/// }
650/// ```
651///
652/// ### Derive `Add` from `impl Add`
653///
654/// By applying `#[derive_ex(Add)]` to one of the following, you can implement the remaining three.
655///
656/// - `impl Add<T> for T`
657/// - `impl Add<T> for &T`
658/// - `impl Add<&T> for T`
659/// - `impl Add<&T> for &T`
660///
661/// `T` must implement `Clone`, except when `#[derive_ex(Add)]` is applied to `impl Add<&T> for &T`.
662///
663/// ```rust
664/// use derive_ex::derive_ex;
665/// use std::ops::Add;
666///
667/// #[derive(Clone)]
668/// struct A {
669/// a: u8,
670/// }
671///
672/// #[derive_ex(Add)]
673/// impl Add<A> for A {
674/// type Output = A;
675/// fn add(self, rhs: A) -> Self::Output {
676/// A { a: self.a + rhs.a }
677/// }
678/// }
679/// ```
680///
681/// The above code generates the following code.
682///
683/// ```rust
684/// # use std::ops::Add;
685/// #
686/// # #[derive(Clone)]
687/// # struct A {
688/// # a: u8,
689/// # }
690/// #
691/// # impl Add<A> for A {
692/// # type Output = A;
693/// # fn add(self, rhs: A) -> Self::Output {
694/// # A { a: self.a + rhs.a }
695/// # }
696/// # }
697/// impl Add<&A> for A {
698/// type Output = A;
699/// fn add(self, rhs: &A) -> Self::Output {
700/// self + rhs.clone()
701/// }
702/// }
703/// impl Add<A> for &A {
704/// type Output = A;
705/// fn add(self, rhs: A) -> Self::Output {
706/// self.clone() + rhs
707/// }
708/// }
709/// impl Add<&A> for &A {
710/// type Output = A;
711/// fn add(self, rhs: &A) -> Self::Output {
712/// self.clone() + rhs.clone()
713/// }
714/// }
715/// ```
716///
717/// ### Derive `Add` from `impl AddAssign`
718///
719/// By applying `#[derive_ex(Add)]` to `impl AddAssign<Rhs> for T`, you can implement `Add<Rhs> for T`.
720///
721/// ```rust
722/// use derive_ex::derive_ex;
723/// use std::ops::AddAssign;
724///
725/// struct X {
726/// a: u8,
727/// b: u32,
728/// }
729/// #[derive_ex(Add)]
730/// impl std::ops::AddAssign<u8> for X {
731/// fn add_assign(&mut self, rhs: u8) {
732/// self.a += rhs;
733/// self.b += rhs as u32;
734/// }
735/// }
736/// ```
737///
738/// The above code generates the following code.
739///
740/// ```rust
741/// # use derive_ex::derive_ex;
742/// # use std::ops::AddAssign;
743/// #
744/// # struct X {
745/// # a: u8,
746/// # b: u32,
747/// # }
748/// # impl AddAssign<u8> for X {
749/// # fn add_assign(&mut self, rhs: u8) {
750/// # self.a += rhs;
751/// # self.b += rhs as u32;
752/// # }
753/// # }
754/// use std::ops::Add;
755///
756/// impl Add<u8> for X {
757/// type Output = X;
758/// fn add(mut self, rhs: u8) -> Self::Output {
759/// self += rhs;
760/// self
761/// }
762/// }
763/// ```
764///
765/// ## `AddAssign`-like
766///
767/// In this document, `AddAssign` is used as an example, but all of the following traits can be used in the same way.
768///
769/// - `AddAssign`
770/// - `BitAndAssign`
771/// - `BitOrAssign`
772/// - `BitXorAssign`
773/// - `DivAssign`
774/// - `MulAssign`
775/// - `RemAssign`
776/// - `ShlAssign`
777/// - `ShrAssign`
778/// - `SubAssign`
779///
780/// ### Derive `AddAssign` from struct definition
781///
782/// You can use `#[derive(AddAssign)]` on struct definition to derive `Assign`.
783///
784/// ```rust
785/// use derive_ex::derive_ex;
786///
787/// #[derive_ex(AddAssign)]
788/// struct X {
789/// a: u8,
790/// b: u32,
791/// }
792/// ```
793///
794/// The above code generates the following code.
795///
796/// ```rust
797/// # use derive_ex::derive_ex;
798/// # use ::core::ops::Add;
799/// #
800/// # struct X {
801/// # a: u8,
802/// # b: u32,
803/// # }
804/// use std::ops::AddAssign;
805///
806/// impl AddAssign<X> for X {
807/// fn add_assign(&mut self, rhs: X) {
808/// self.a += rhs.a;
809/// self.b += rhs.b;
810/// }
811/// }
812/// impl AddAssign<&X> for X {
813/// fn add_assign(&mut self, rhs: &X) {
814/// self.a += &rhs.a;
815/// self.b += &rhs.b;
816/// }
817/// }
818/// ```
819///
820/// ### Derive `AddAssign` from `impl Add`
821///
822/// By applying `#[derive_ex(AddAssign)]` to `impl Add<Rhs> for T` or `impl Add<Rhs> for &T`, you can implement `AddAssign<Rhs> for T`.
823///
824/// When `#[derive_ex(AddAssign)]` is applied to `impl Add<Rhs> for &T`, `T` must implement `Clone`.
825///
826/// When `#[derive_ex(AddAssign)]` is applied to `impl Add<Rhs> for T`, `T` does not have to implement `Clone`.
827///
828/// ```rust
829/// use derive_ex::derive_ex;
830/// use std::ops::Add;
831///
832/// #[derive(Clone)]
833/// struct X {
834/// a: u8,
835/// b: u32,
836/// }
837///
838/// #[derive_ex(AddAssign)]
839/// impl Add<u8> for X {
840/// type Output = X;
841/// fn add(mut self, rhs: u8) -> Self::Output {
842/// self.a += rhs;
843/// self.b += rhs as u32;
844/// self
845/// }
846/// }
847/// ```
848///
849/// ```rust
850/// # use derive_ex::derive_ex;
851/// # use std::ops::Add;
852/// #
853/// # #[derive(Clone)]
854/// # struct X {
855/// # a: u8,
856/// # b: u32,
857/// # }
858/// #
859/// # impl Add<u8> for X {
860/// # type Output = X;
861/// # fn add(mut self, rhs: u8) -> Self::Output {
862/// # self.a += rhs;
863/// # self.b += rhs as u32;
864/// # self
865/// # }
866/// # }
867/// use std::ops::AddAssign;
868///
869/// impl AddAssign<u8> for X {
870/// fn add_assign(&mut self, rhs: u8) {
871/// *self = self.clone() + rhs;
872/// }
873/// }
874/// ```
875///
876/// ### Derive both `Add` and `AddAssign` from `impl Add`
877///
878/// Applying `#[derive_ex(Add, AddAssign)]` to one of the four below will implement the other three, plus generate the same code as when `#[derive_ex(AddAssign)]` is applied to `impl Add<T> for &T` and `impl Add<&T> for &T`.
879///
880/// - `impl Add<T> for T`
881/// - `impl Add<T> for &T`
882/// - `impl Add<&T> for T`
883/// - `impl Add<&T> for &T`
884///
885/// ## `Not`-like
886///
887/// In this document, `Not` is used as an example, but all of the following traits can be used in the same way.
888///
889/// - `Not`
890/// - `Neg`
891///
892/// You can use `#[derive_ex(Not)]` to implement `Not`.
893///
894/// ```rust
895/// use derive_ex::derive_ex;
896///
897/// #[derive_ex(Not)]
898/// struct X {
899/// a: bool,
900/// b: bool,
901/// }
902/// ```
903///
904/// The above code generates the following code.
905///
906/// ```rust
907/// # use derive_ex::derive_ex;
908/// #
909/// # struct X {
910/// # a: bool,
911/// # b: bool,
912/// # }
913/// use std::ops::Not;
914///
915/// impl Not for X {
916/// type Output = X;
917/// fn not(self) -> Self::Output {
918/// X {
919/// a: !self.a,
920/// b: !self.b,
921/// }
922/// }
923/// }
924/// impl Not for &X {
925/// type Output = X;
926/// fn not(self) -> Self::Output {
927/// X {
928/// a: !&self.a,
929/// b: !&self.b,
930/// }
931/// }
932/// }
933/// ```
934///
935/// # Specify trait bound
936///
937/// If the type definition or impl item to which `#[derive_ex]` is applied has generic parameters, then by default, trait bound required by the auto-generated code is set.
938///
939/// You can change the generated trait bound by specifying `bound(...)` in attribute.
940///
941/// `bound(...)` can be used in the following places, the lower the number, the higher the priority.
942///
943/// | | struct, enum | variant | field |
944/// | ------------------------------------- | ------------ | ------- | ----- |
945/// | `#[trait_name(bound(...))]` | 1 | 4 | 7 |
946/// | `#[derive_ex(TraitName(bound(...)))]` | 2 | 5 | 8 |
947/// | `#[derive_ex(TraitName, bound(...))]` | 3 | 6 | 9 |
948///
949/// ```rust
950/// use derive_ex::derive_ex;
951///
952/// #[derive_ex(Default(bound(T)/* <-- 2 */), bound(T)/* <-- 3 */)]
953/// #[default(_, bound(T))] // <-- 1
954/// enum X<T> {
955/// A,
956/// #[derive_ex(Default(bound(T)/* <-- 5 */), bound(T)/* <-- 6 */)]
957/// #[default(_, bound(T))] // <-- 4
958/// B {
959/// #[derive_ex(Default(bound(T)/* <-- 8 */), bound(T)/* <-- 9 */)]
960/// #[default(_, bound(T))] // <-- 7
961/// t: T,
962/// },
963/// }
964/// ```
965///
966/// In 3, 6, and 9, common trait bound can be set for multiple traits by using it as like `#[derive_ex(Clone, Default, bound(T))]`.
967///
968/// Trait bound can be specified in the following three ways.
969///
970/// - Type (`T`)
971/// - Predicate (`T : TraitName`)
972/// - Default (`..`)
973///
974/// ## `#[bound(T)]`
975///
976/// If you specify a type in `#[bound(...)]`, make sure that the specified type implements the trait to be generated.
977///
978/// ```rust
979/// use derive_ex::derive_ex;
980///
981/// #[derive_ex(Default, Clone, bound(T))]
982/// struct X<T>(Box<T>);
983/// ```
984///
985/// The above code generates the following code.
986///
987/// By `bound(T)`, `Box<T> : Default` is changed to `T : Default` and `Box<T> : Clone` is changed to `T : Clone`.
988///
989/// ```rust
990/// # use derive_ex::derive_ex;
991/// # struct X<T>(Box<T>);
992/// impl<T> Default for X<T>
993/// where
994/// T: Default,
995/// {
996/// fn default() -> Self {
997/// X(Box::default())
998/// }
999/// }
1000///
1001/// impl<T> Clone for X<T>
1002/// where
1003/// T: Clone,
1004/// {
1005/// fn clone(&self) -> Self {
1006/// X(self.0.clone())
1007/// }
1008/// fn clone_from(&mut self, source: &Self) {
1009/// self.0.clone_from(&source.0)
1010/// }
1011/// }
1012/// ```
1013///
1014/// ## `#[bound(T : TraitName)]`
1015///
1016/// If a predicate is specified, it is used as-is.
1017///
1018/// ```rust
1019/// use derive_ex::derive_ex;
1020///
1021/// #[derive_ex(Clone, bound(T : Clone + Copy))]
1022/// struct X<T>(T);
1023/// ```
1024///
1025/// The above code generates the following code.
1026///
1027/// By `bound(T : Clone + Copy)`, `T : Clone` is changed to `T : Clone + Copy`.
1028///
1029/// ```rust
1030/// # use derive_ex::derive_ex;
1031/// # struct X<T>(T);
1032/// impl<T> Clone for X<T>
1033/// where
1034/// T: Clone + Copy,
1035/// {
1036/// fn clone(&self) -> Self {
1037/// X(self.0.clone())
1038/// }
1039/// fn clone_from(&mut self, source: &Self) {
1040/// self.0.clone_from(&source.0)
1041/// }
1042/// }
1043/// ```
1044///
1045/// ## `#[bound(..)]`
1046///
1047/// `..` means default trait bound.
1048///
1049/// If `..` is specified, the lower priority trait bound is used.
1050///
1051/// ```rust
1052/// use derive_ex::derive_ex;
1053///
1054/// #[derive_ex(Clone, bound(T : Copy, ..))]
1055/// struct X<T>(T);
1056/// ```
1057///
1058/// The above code generates the following code.
1059///
1060/// By `bound(T : Copy, ..)` ,`T : Copy` is added to `T : Clone` which is the default trait bound.
1061///
1062/// ```rust
1063/// # use derive_ex::derive_ex;
1064/// # struct X<T>(T);
1065/// impl<T> Clone for X<T>
1066/// where
1067/// T: Clone,
1068/// T: Copy,
1069/// {
1070/// fn clone(&self) -> Self {
1071/// X(self.0.clone())
1072/// }
1073/// fn clone_from(&mut self, source: &Self) {
1074/// self.0.clone_from(&source.0)
1075/// }
1076/// }
1077/// ```
1078///
1079/// ## `#[bound()]`
1080///
1081/// An empty argument means no constraint.
1082///
1083/// ```rust
1084/// use derive_ex::derive_ex;
1085/// use std::rc::Rc;
1086///
1087/// #[derive_ex(Clone, bound())]
1088/// struct X<T>(Rc<T>);
1089/// ```
1090///
1091/// The above code generates the following code.
1092///
1093/// By `bound()`, `where Rc<T> : Clone` is removed.
1094///
1095/// ```rust
1096/// # use std::rc::Rc;
1097/// # struct X<T>(Rc<T>);
1098/// impl<T> Clone for X<T> {
1099/// fn clone(&self) -> Self {
1100/// X(self.0.clone())
1101/// }
1102/// fn clone_from(&mut self, source: &Self) {
1103/// self.0.clone_from(&source.0)
1104/// }
1105/// }
1106/// ```
1107///
1108/// # Display generated code
1109///
1110/// The generated code is output as an error message by using `#[derive_ex(dump)]`.
1111///
1112/// ```compile_fail
1113/// #[derive_ex(Clone, dump)]
1114/// struct X<T>(T);
1115/// ```
1116///
1117/// The above code causes the following error.
1118///
1119/// ```txt
1120/// error: dump:
1121/// impl < T > :: core :: clone :: Clone for X < T > where T : :: core :: clone ::
1122/// Clone,
1123/// {
1124/// fn clone(& self) -> Self
1125/// { X(< T as :: core :: clone :: Clone > :: clone(& self.0),) } fn
1126/// clone_from(& mut self, source : & Self)
1127/// {
1128/// < T as :: core :: clone :: Clone > ::
1129/// clone_from(& mut self.0, & source.0) ;
1130/// }
1131/// }
1132/// ```
1133///
1134/// As with `bound(...)`, `dump` can be applied to multiple traits by writing `#[derive_ex(Clone, Default, dump)]`.
1135// #[include_doc("../../doc/derive_ex.md", end)]
1136#[proc_macro_attribute]
1137pub fn derive_ex(
1138 attr: proc_macro::TokenStream,
1139 item: proc_macro::TokenStream,
1140) -> proc_macro::TokenStream {
1141 let mut item: TokenStream = item.into();
1142 match build(attr.into(), item.clone()) {
1143 Ok(s) => s,
1144 Err(e) => {
1145 item.extend(e.to_compile_error());
1146 item
1147 }
1148 }
1149 .into()
1150}
1151
1152/// Use attribute macro [`macro@derive_ex`] as derive macro.
1153///
1154/// [`macro@derive_ex`], being an attribute macro designed to mimic the functionality of the derive macro,
1155/// may cause rust-analyzer's assistance to not work correctly in certain cases.
1156///
1157/// Adding `#[derive(Ex)]` to an item with `#[derive_ex]` will allow rust-analyzer's assistance to work correctly.
1158///
1159/// In the example below, without `#[derive(Ex)]`,
1160/// the jump from `value: String` to the definition of `String` is not possible,
1161/// but with `#[derive(Ex)]`, it is possible.
1162///
1163/// ```
1164/// use derive_ex::Ex;
1165///
1166/// #[derive(Ex)]
1167/// #[derive_ex(Eq, PartialEq)]
1168/// struct X {
1169/// #[eq(key = $.len())]
1170/// value: String,
1171/// }
1172/// ```
1173#[proc_macro_derive(
1174 Ex,
1175 attributes(derive_ex, ord, partial_ord, eq, partial_eq, hash, debug, default)
1176)]
1177pub fn derive_ex_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
1178 let input: TokenStream = input.into();
1179 match item_type::build_derive(input) {
1180 Ok(s) => s,
1181 Err(e) => e.to_compile_error(),
1182 }
1183 .into()
1184}
1185
1186fn build(attr: TokenStream, item: TokenStream) -> Result<TokenStream> {
1187 let mut item: Item = parse2(item)?;
1188 let ts = match &mut item {
1189 Item::Struct(item_struct) => item_type::build_by_item_struct(attr, item_struct),
1190 Item::Enum(item_enum) => item_type::build_by_item_enum(attr, item_enum),
1191 Item::Impl(item_impl) => item_impl::build_by_item_impl(attr, item_impl),
1192 _ => bail!(
1193 _,
1194 "`#[derive_ex]` can be specified only for `struct`, `enum`, or `impl`.",
1195 ),
1196 }
1197 .unwrap_or_else(|e| e.to_compile_error());
1198
1199 Ok(quote!(#item #ts))
1200}