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}