amplify_derive/
lib.rs

1// Rust language amplification derive library providing multiple generic trait
2// implementations, type wrappers, derive macros and other language enhancements
3//
4// Written in 2019-2020 by
5//     Dr. Maxim Orlovsky <orlovsky@pandoracore.com>
6//     Elichai Turkel <elichai.turkel@gmail.com>
7//
8// To the extent possible under law, the author(s) have dedicated all
9// copyright and related and neighboring rights to this software to
10// the public domain worldwide. This software is distributed without
11// any warranty.
12//
13// You should have received a copy of the MIT License
14// along with this software.
15// If not, see <https://opensource.org/licenses/MIT>.
16
17//! Amplifying Rust language capabilities: multiple generic trait
18//! implementations, type wrappers, derive macros.
19
20#[macro_use]
21extern crate quote;
22#[macro_use]
23extern crate syn;
24extern crate proc_macro;
25
26#[macro_use]
27mod util;
28
29mod as_any;
30mod display;
31mod error;
32mod from;
33mod getters;
34mod wrapper;
35
36use proc_macro::TokenStream;
37use syn::DeriveInput;
38
39/// # Usage
40///
41/// 1. Generate [`Display`] descriptions using other formatting trait:
42///    ```
43///     # #[macro_use] extern crate amplify_derive;
44///     #[derive(Display, Debug)]
45///     #[display(Debug)]
46///     enum Some {
47///         Once,
48///         Twice(u8)
49///     }
50///    ```
51/// 2. Use existing function for displaying descriptions:
52///    ```
53///     # #[macro_use] extern crate amplify_derive;
54///     #[macro_use] extern crate amplify;
55///
56///     #[derive(Display)]
57///     #[display(Int::print)]
58///     union Int { uint: u32, int: i32 };
59///     impl Int {
60///         pub fn print(&self) -> String {
61///             s!("Integer representation")
62///         }
63///     }
64///
65///     pub trait ToSpecialString {
66///         fn to_special_string(&self) -> String {
67///             s!("Special string")
68///         }
69///     }
70///
71///     #[derive(Display)]
72///     #[display(Some::to_special_string)]
73///     struct Some { uint: u32, int: i32 };
74///     impl ToSpecialString for Some {}
75///
76///     assert_eq!(
77///         format!("{}", Int { uint: 2 }),
78///         s!("Integer representation")
79///     );
80///
81///     #[derive(Display)]
82///     #[display(some_fmt)]
83///     enum Enum { Once(u8), Twice };
84///     fn some_fmt(_: &Enum) -> String { s!("Some") }
85///     assert_eq!(format!("{}", Enum::Once(3)), s!("Some"))
86///    ```
87///    Formatting function must return [`String`] and take a single `self`
88///    argument (if you need formatting with streamed output, use one of
89///    existing formatting traits as shown in pt. 1).
90/// 3. Custom format string:
91///    ```
92///     # #[macro_use] extern crate amplify_derive;
93///     #[derive(Display)]
94///     #[display("({x}, {y})")]
95///     struct Point { x: u32, y: u32 }
96///     assert_eq!(format!("{}", Point { x: 0, y: 1 }), "(0, 1)");
97///
98///     #[derive(Display)]
99///     #[display("[{vec}]")]
100///     struct Data { #[display(separator = ", ")] vec: Vec<String> }
101///     assert_eq!(format!("{}", Data { vec: vec!["foo".into(), "bar".into()]}),
102///         "[foo, bar]");
103///    ```
104/// 4. Support for alternative formatting with `alt` parameter:
105///    ```
106///     # #[macro_use] extern crate amplify_derive;
107///     #[derive(Display)]
108///     #[display("({x}, {y})", alt = "{x}:{y}")]
109///     struct Point { x: u32, y: u32 }
110///     assert_eq!(format!("{}", Point { x: 0, y: 1 }), "(0, 1)");
111///     assert_eq!(format!("{:#}", Point { x: 0, y: 1 }), "0:1");
112///    ```
113/// 5. Use of doc comments for descrition representation. In this case doc
114///    comments may also contain formatting like in the case 3:
115///    ```
116///     # #[macro_use] extern crate amplify_derive;
117///     #[macro_use] extern crate amplify;
118///
119///     /// Example enum with doc comments converted into display
120///     #[derive(Display)]
121///     #[display(doc_comments)]
122///     enum Variants {
123///         /// Letter A.
124///         /// Multiline comments are also working, but joined together
125///         ///
126///         /// Empty line is replaced with line break
127///         /// \nYou may also use this way
128///         /// \n
129///         /// The above will still result in a single line break
130///         A,
131///         /// Letter B
132///         B,
133///         /// This comment is ignored
134///         #[display("Letter C")]
135///         C,
136///         /// Letter {0}
137///         Letter(String),
138///         /// You can omit parameters and just have a normal doc comment
139///         Number(u8),
140///         /// ... for variants with named fields as well
141///         Named { some: String }
142///     };
143///
144///     assert_eq!(
145///         format!("{}", Variants::A),
146///         "Letter A. Multiline comments are also working, but joined \
147///         together\nEmpty line is replaced with line break\nYou may also use \
148///         this way\nThe above will still result in a single line break"
149///     );
150///     assert_eq!(format!("{}", Variants::C), "Letter C");
151///     assert_eq!(format!("{}", Variants::Letter(s!("K"))), "Letter K");
152///    ```
153///    You can also mix in this mode with other fors of display tags on a
154///    specific options; in this case doc comments are ignored
155/// 6. Support of unit structs and newtypes:
156///    ```
157///     # #[macro_use] extern crate amplify_derive;
158///     /// Some unit struct
159///     #[derive(Clone, Debug, Display, Error)]     
160///     #[display(doc_comments)]
161///     pub struct UnitStruct;
162///
163///     /// displaying the wrapped type data: '{0}'.
164///     #[derive(Clone, PartialEq, Eq, Debug, Display)]
165///     #[display(doc_comments)]
166///     pub struct NewType(pub String);
167///    ```
168/// 7. Print the name of enum variant in lowercase/uppercase:
169///    ```
170///     # #[macro_use] extern crate amplify_derive;
171///     #[derive(Display)]
172///     #[display(lowercase)]
173///     enum Message {
174///         Quit,
175///         Move { x: i32, y: i32 },
176///         Write(String),
177///         ChangeColor(i32, i32, i32),
178///     }
179///
180///     #[derive(Display)]
181///     #[display(uppercase)]
182///     enum Event {
183///         Init,
184///         Load(Message),
185///     }
186///
187///
188///     assert_eq!(format!("{}", Message::Quit), "quit");
189///     assert_eq!(format!("{}", Message::Move{ x: 1, y: 2 }),
190///         "move { x: 1, y: 2 }");
191///     assert_eq!(format!("{}", Message::Write(String::from("msg"))),
192///         "write(msg)");
193///     assert_eq!(format!("{}", Message::ChangeColor(255, 0, 0)),
194///         "changecolor(255, 0, 0)");
195///     assert_eq!(format!("{}", Event::Init), "INIT");
196///     assert_eq!(format!("{}", Event::Load(Message::ChangeColor(0, 255, 0))),
197///         "LOAD(changecolor(0, 255, 0))");
198///    ```
199/// # Example
200///
201/// Advanced use with enums:
202/// ```
203/// # #[macro_use] extern crate amplify_derive;
204/// #[derive(Display)]
205/// enum Test {
206///     Some,
207///
208///     #[display("OtherName")]
209///     Other,
210///
211///     /// Document comment working as display string
212///     Commented,
213///
214///     Named {
215///         x: u8,
216///     },
217///
218///     #[display("Custom{x}", alt = "this is alternative")]
219///     NamedCustom {
220///         x: u8,
221///     },
222///
223///     #[display(inner)]
224///     Inner {
225///         a: String,
226///     },
227///
228///     Unnamed(u16),
229///
230///     // NB: Use indexes for tuple values
231///     #[display("Custom{0}")]
232///     UnnamedCustom(String),
233/// }
234///
235/// assert_eq!(format!("{}", Test::Some), "Some");
236/// assert_eq!(format!("{}", Test::Other), "OtherName");
237/// assert_eq!(format!("{}", Test::Named { x: 1 }), "Named { .. }");
238/// assert_eq!(format!("{}", Test::Unnamed(5)), "Unnamed(..)");
239/// assert_eq!(format!("{}", Test::NamedCustom { x: 8 }), "Custom8");
240/// assert_eq!(format!("{:#}", Test::NamedCustom { x: 8 }), "this is alternative");
241/// assert_eq!(format!("{}", Test::UnnamedCustom("Test".to_string())), "CustomTest");
242/// ```
243///
244/// Use with tuple types:
245/// ```
246/// # #[macro_use] extern crate amplify_derive;
247/// #[derive(Clone, Copy, Debug, Display)]
248/// #[display("{0}")]
249/// struct Tuple(u8);
250///
251/// #[derive(Clone, Copy, Debug, Display)]
252/// #[display(inner)] // `inner` is synonym to "{0}"
253/// struct Tuple2(u8);
254///
255/// assert_eq!(format!("{}", Tuple(5)), format!("{}", Tuple2(5)))
256/// ```
257///
258/// Using inner enum variant representation, defaulting to the variant name
259/// if the variant does not have inner data:
260/// ```
261/// # #[macro_use] extern crate amplify_derive;
262/// use std::net::{IpAddr, Ipv4Addr};
263///
264/// #[derive(Clone, Copy, Debug, Display)]
265/// #[display(inner)] // `inner` is synonym to "{0}"
266/// enum Variants {
267///     First,
268///     Second,
269///     WithData(u8),
270///     WithComplexData(IpAddr),
271/// };
272///
273/// assert_eq!(Variants::First.to_string(), "First");
274/// assert_eq!(Variants::WithData(5).to_string(), "5");
275/// assert_eq!(
276///     Variants::WithComplexData(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))).to_string(),
277///     "127.0.0.1"
278/// );
279/// ```
280#[proc_macro_derive(Display, attributes(display))]
281pub fn derive_display(input: TokenStream) -> TokenStream {
282    let derive_input = parse_macro_input!(input as DeriveInput);
283    display::inner(derive_input)
284        .unwrap_or_else(|e| e.to_compile_error())
285        .into()
286}
287
288/// Error derive macro works to the full extend only when other derive macros
289/// are used. With `#[derive(Display)]` and `[display(doc_comments)]` it uses
290/// doc comments for generating error descriptions; with `#[derive(From)]` it
291/// may automatically implement transofrations from other error types.
292///
293/// # Example
294///
295/// ```
296/// # #[macro_use] extern crate amplify_derive;
297/// #[derive(Debug, Display, Error)]
298/// #[display(doc_comments)]
299/// enum Error {
300///     /// I/O operation error
301///     Io,
302///     /// Math overflow
303///     Overflow,
304///     /// Zero division with {0}
305///     ZeroDivision(u16),
306/// }
307///
308/// assert_eq!(format!("{}", Error::Io), "I/O operation error");
309/// assert_eq!(format!("{}", Error::Overflow), "Math overflow");
310/// assert_eq!(format!("{}", Error::ZeroDivision(2)), "Zero division with 2");
311/// ```
312#[proc_macro_derive(Error)]
313pub fn derive_error(input: TokenStream) -> TokenStream {
314    let derive_input = parse_macro_input!(input as DeriveInput);
315    error::inner(derive_input)
316        .unwrap_or_else(|e| e.to_compile_error())
317        .into()
318}
319
320/// Implements [`From`] trait for the whole entity and/or its separate fields.
321/// Works well with `#[derive(Error)]` and, in many cases may require
322/// [`Default`] implementation (for details, pls see Examples below)
323///
324/// # Examples
325///
326/// ```
327/// # #[macro_use] extern crate amplify_derive;
328/// #
329/// #[derive(From, Default)]
330/// #[from(::std::io::Error)]
331/// // Structure may contain no parameters
332/// pub struct IoErrorUnit;
333///
334/// #[derive(From, Default)]
335/// #[from(::std::io::Error)] // When no explicit binding is given, structure must implement `Default`
336/// pub struct IoError {
337///     details: String,
338///
339///     #[from]
340///     kind: IoErrorUnit,
341/// }
342///
343/// #[derive(From)]
344/// pub enum Error {
345///     // You can specify multiple conversions with separate attributes
346///     #[from(::std::io::Error)]
347///     #[from(IoError)]
348///     Io,
349///
350///     #[from]
351///     Format(::std::fmt::Error),
352///
353///     #[from]
354///     WithFields { details: ::std::str::Utf8Error },
355///
356///     MultipleFields {
357///         // ...and you can also covert error type
358///         #[from(IoErrorUnit)]
359///         // rest of parameters must implement `Default`
360///         io: IoError,
361///         details: String,
362///     },
363/// }
364///
365/// #[derive(Clone, Copy, PartialEq, Eq, Hash, Default, Debug, From)]
366/// pub struct Wrapper(u32, i16);
367/// ```
368///
369/// If you use rust nightly and `#![feature(never_type)]` for [`!`], you can
370/// even do the following:
371/// ```ignore
372/// #![feature(never_type)]
373///
374/// #[macro_use]
375/// extern crate amplify_derive;
376///
377/// #[derive(From)]
378/// pub enum Error {
379///     // ... other error types
380///     #[from(!)]
381///     NeverType,
382/// }
383///
384/// # fn main () {
385/// # }
386/// ```
387#[proc_macro_derive(From, attributes(from))]
388pub fn derive_from(input: TokenStream) -> TokenStream {
389    let derive_input = parse_macro_input!(input as DeriveInput);
390    from::inner(derive_input)
391        .unwrap_or_else(|e| e.to_compile_error())
392        .into()
393}
394
395/// Trait `amplify::AsAny` allows simple conversion of any type into a
396/// generic "thick" pointer `&dyn Any` (see [`::core::any::Any`]), that can be
397/// later converted back to the original type with a graceful failing for all
398/// other conversions. `AsAny` derive macro allows to implement this trait for
399/// arbitrary time without much hussle:
400///
401/// # Example
402///
403/// ```
404/// # #[macro_use] extern crate amplify_derive;
405/// extern crate amplify;
406/// use amplify::AsAny;
407///
408/// #[derive(AsAny, Copy, Clone, PartialEq, Eq, Debug)]
409/// struct Point {
410///     pub x: u64,
411///     pub y: u64,
412/// }
413///
414/// #[derive(AsAny, PartialEq, Debug)]
415/// struct Circle {
416///     pub radius: f64,
417///     pub center: Point,
418/// }
419///
420/// let mut point = Point { x: 1, y: 2 };
421/// let point_ptr = point.as_any();
422///
423/// let mut circle = Circle {
424///     radius: 18.,
425///     center: point,
426/// };
427/// let circle_ptr = circle.as_any();
428///
429/// assert_eq!(point_ptr.downcast_ref(), Some(&point));
430/// assert_eq!(circle_ptr.downcast_ref(), Some(&circle));
431/// assert_eq!(circle_ptr.downcast_ref::<Point>(), None);
432///
433/// let p = point_ptr.downcast_ref::<Point>().unwrap();
434/// assert_eq!(p.x, 1)
435/// ```
436#[proc_macro_derive(AsAny)]
437pub fn derive_as_any(input: TokenStream) -> TokenStream {
438    let derive_input = parse_macro_input!(input as DeriveInput);
439    as_any::inner(derive_input)
440        .unwrap_or_else(|e| e.to_compile_error())
441        .into()
442}
443
444/// Derives getter methods for structures. The return type and naming of the
445/// methods depends on the provided attribute arguments.
446///
447/// # Attribute `#[getter(...)]`
448///
449/// Macro is provided with `#[getter]` attribute, which may be used on both
450/// type and field level. See following sections describing its arguments
451///
452/// ## Arguments
453///
454/// ### Method derivation arguments
455/// Method derivation arguments define which forms of methods should be derived.
456/// Applicable both at the type level, where it defines a set of derived methods
457/// for all fields (unless they are overrided on the field level) – or on the
458/// field level, where it overrides/replaces the default set of methods with a
459/// new one.
460///
461/// Attribute takes a list of arguments in form of verbatim literals:
462/// - `as_copy`: derives methods returning copy of the field value. Will error
463///   at compile time on types which does not implement `Copy`
464/// - `as_clone`: derives methods returning cloned value; will conflict with
465///   `as_copy`. Errors at compile time on types which does not implement
466///   `Clone`.
467/// - `as_ref`: derives method returning reference. If provided together with
468///   either `as_copy` or `as_clone`, method name returning reference is
469///   suffixed with `_ref`; otherwise the base name is used (see below)
470/// - `as_mut`: derives method returning mutable reference. Method name is
471///   suffixed with `_mut`
472/// - `all`: equivalent to `as_clone, as_ref, as_mut`
473///
474/// **Can be used**: at type and field level
475///
476/// **Defaults to**: `as_ref`
477///
478/// ### `#[getter(skip)]`
479/// Skips derivation of a all gettter methods for this field
480///
481/// ### `#[getter(prefix = "...")]`
482/// Defines prefix added to all derived getter method names.
483///
484/// **Defaults to**: none (no prefix added)
485///
486/// **Can be used**: at type level
487///
488/// ### `#[getter(base_name = "...")]`
489/// Defines base name for the getter method. Base name is prefixed with prefix
490/// from a type-level getter `prefix` attribute (if the one is specified) and
491/// suffix, which is method-specific (see `methods` argument description above).
492///
493/// **Defaults to**: field name
494///
495/// **Can be used**: at field level
496///
497/// # Errors
498///
499/// Enums and units are not supported; attempt to derive `Getters` on them will
500/// result in a compile-time error.
501///
502/// Deriving getters on unit structs and structs with unnamed fields (tupe
503/// structs) is not supported (since it's meaningless), and results in a error.
504///
505/// Additionally to these two cases, macro errors on argument inconsistencies,
506/// as described in the argument-specific sections.
507///
508/// # Examples
509///
510/// Basic use:
511///
512/// ```
513/// # #[macro_use] extern crate amplify_derive;
514/// #[derive(Getters, Default)]
515/// struct One {
516///     vec: Vec<u8>,
517///     defaults: String,
518///     #[getter(as_copy)]
519///     pub flag: bool,
520///     #[getter(as_copy)]
521///     pub(self) field: u8,
522/// }
523///
524/// let mut one = One::default();
525/// assert_eq!(one.vec(), &Vec::<u8>::default());
526/// assert_eq!(one.defaults(), "");
527/// assert_eq!(one.flag(), false);
528/// assert_eq!(one.field(), 0);
529/// ```
530///
531/// Important, that field-level arguments to override struct-level arguments:
532/// ```
533/// # #[macro_use] extern crate amplify_derive;
534/// #[derive(Getters, Default)]
535/// #[getter(as_copy)]
536/// struct Other {
537///     #[getter(as_ref)]
538///     vec: Vec<u8>,
539///     #[getter(as_clone)]
540///     defaults: String,
541///     pub flag: bool,
542///     pub(self) field: u8,
543/// }
544///
545/// let mut other = Other::default();
546/// assert_eq!(other.vec(), &Vec::<u8>::default());
547/// assert_eq!(other.defaults(), String::from(""));
548/// ```
549///
550/// Advanced use: please pay attention that `as_mut` on a struct level is not
551/// removed by the use of `as_copy` at field level.
552///
553/// ```
554/// # #[macro_use] extern crate amplify_derive;
555/// #[derive(Getters, Default)]
556/// #[getter(as_mut, prefix = "get_")]
557/// struct One {
558///     /// Contains byte representation of the data
559///     #[getter(all, base_name = "bytes")]
560///     vec: Vec<u8>,
561///
562///     defaults: String,
563///
564///     #[getter(as_copy)]
565///     pub flag: bool,
566///
567///     #[getter(skip)]
568///     pub(self) field: u8,
569/// }
570///
571/// let mut one = One::default();
572/// assert_eq!(one.get_bytes_ref(), &Vec::<u8>::default());
573/// *one.get_bytes_mut() = vec![0, 1, 2];
574/// assert_eq!(one.get_defaults(), "");
575/// assert_eq!(one.get_defaults_mut(), "");
576/// assert_eq!(one.get_bytes(), vec![0, 1, 2]);
577/// assert_eq!(one.get_flag(), bool::default());
578/// assert_eq!(one.get_flag_mut(), &mut bool::default());
579/// let flag = one.get_flag_mut();
580/// *flag = true;
581/// assert_eq!(one.get_flag(), true);
582/// assert_eq!(one.flag, one.get_flag());
583/// // method does not exist: assert_eq!(one.get_field(), u8::default());
584/// ```
585///
586/// this will end up in the following generated code:
587/// ```
588/// # struct One {
589/// #    vec: Vec<u8>,
590/// #    pub flag: bool,
591/// #    pub(self) field: u8,
592/// # }
593///
594/// impl One {
595///     #[doc = "Method cloning [`One::vec`] field.\n"]
596///     #[doc = " Contains byte representation of the data"]
597///     #[inline]
598///     pub fn get_bytes(&self) -> Vec<u8> { self.vec.clone() }
599///
600///     #[doc = "Method borrowing [`One::vec`] field.\n"]
601///     #[doc = " Contains byte representation of the data"]
602///     #[inline]
603///     pub fn get_bytes_ref(&self) -> &Vec<u8> { &self.vec }
604///
605///     #[doc = "Method returning mutable borrow of [`One::vec`] field.\n"]
606///     #[doc = " Contains byte representation of the data"]
607///     #[inline]
608///     pub fn get_bytes_mut(&mut self) -> &mut Vec<u8> { &mut self.vec }
609///
610///     #[doc = "Method returning copy of [`One::flag`] field.\n"]
611///     #[inline]
612///     pub fn get_flag(&self) -> bool { self.flag }
613///
614///     #[doc = "Method returning mutable borrow of [`One::flag`] field.\n"]
615///     #[inline]
616///     pub fn get_flag_mut(&mut self) -> &mut bool { &mut self.flag }
617/// }
618/// ```
619#[proc_macro_derive(Getters, attributes(getter))]
620pub fn derive_getters(input: TokenStream) -> TokenStream {
621    let derive_input = parse_macro_input!(input as DeriveInput);
622    getters::derive(derive_input)
623        .unwrap_or_else(|e| e.to_compile_error())
624        .into()
625}
626
627/// Creates rust new type wrapping existing type. Can be used in structures
628/// containing multiple named or unnamed fields; in this case the field you'd
629/// like to wrap should be marked with `#[wrap]` attribute; otherwise the first
630/// field is assumed to be the wrapped one.
631///
632/// NB: You have to use `derive(From)` in order foe Wrapper to work properly.
633/// Also, in case of multiple fields, each non-wrapped field type must implement
634/// `Default` trait.
635///
636/// Supports automatic implementation of the following traits:
637/// * `amplify::Wrapper`
638/// * [`AsRef`]
639/// * [`core::borrow::Borrow`]
640/// You may skip `AsRef` and `Borrow` implementations with `#[wrapper(NoRefs)]`.
641///
642/// You can implement additional derives, it they are implemented for the
643/// wrapped type, using `#[wrapper()]` proc macro:
644/// 1. Reference access to the inner type:
645///    * `Deref` for implementing [`core::ops::Deref`]
646///    * `AsSlice` for implementing [`AsRef`]`<[u8]>`
647///    * `BorrowSlice` for implementing
648///      [`core::borrow::Borrow`]`<[Self::Inner]>`
649/// 2. Formatting:
650///    * `FromStr` for implementing [`core::str::FromStr`]
651///    * `Debug` for implementing [`core::fmt::Debug`]
652///    * `Display` for implementing [`core::fmt::Display`]
653///    * `FromHex` for implementing [`amplify::hex::FromHex`]
654///    * `LowerHex` for implementing [`core::fmt::LowerHex`]
655///    * `UpperHex` for implementing [`core::fmt::UpperHex`]
656///    * `LowerExp` for implementing [`core::fmt::LowerExp`]
657///    * `UpperExp` for implementing [`core::fmt::UpperExp`]
658///    * `Octal` for implementing [`core::fmt::Octal`]
659/// 3. Indexed access to the inner type:
660///    * `Index` for implementing [`core::ops::Index`]`<usize>`
661///    * `IndexRange` for implementing
662///      [`core::ops::Index`]`<`[`core::ops::Range`]`<usize>>`
663///    * `IndexTo` for implementing
664///      [`core::ops::Index`]`<`[`core::ops::RangeTo`]`<usize>>`
665///    * `IndexFrom` for implementing
666///      [`core::ops::Index`]`<`[`core::ops::RangeFrom`]`<usize>>`
667///    * `IndexInclusive` for implementing
668///      [`core::ops::Index`]`<`[`core::ops::RangeInclusive`]`<usize>>`
669///    * `IndexToInclusive` for implementing
670///      [`core::ops::Index`]`<`[`core::ops::RangeToInclusive`]`<usize>>`
671///    * `IndexFull` for implementing
672///      [`core::ops::Index`]`<`[`core::ops::RangeFrom`]`<usize>>`
673/// 4. Arithmetic operations:
674///    * `Neg` for implementing [`core::ops::Neg`]
675///    * `Add` for implementing [`core::ops::Add`]
676///    * `Sub` for implementing [`core::ops::Sub`]
677///    * `Mul` for implementing [`core::ops::Mul`]
678///    * `Div` for implementing [`core::ops::Div`]
679///    * `Rem` for implementing [`core::ops::Rem`]
680/// 5. Boolean and bit-wise operations:
681///    * `Not` for implementing [`core::ops::Not`]
682///    * `BitAnd` for implementing [`core::ops::BitAnd`]
683///    * `BitOr` for implementing [`core::ops::BitOr`]
684///    * `BitXor` for implementing [`core::ops::BitXor`]
685///    * `Shl` for implementing [`core::ops::Shl`]
686///    * `Shr` for implementing [`core::ops::Shr`]
687///
688/// There are shortcuts for derivations:
689/// * `#[wrapper(Hex)]` will derive both `LowerHex`, `UpperHex` and `FromHex`;
690/// * `#[wrapper(Exp)]` will derive both `LowerExp` and `UpperExp`;
691/// * `#[wrapper(NumberFmt)]` will derive all number formatting traits
692///   (`LowerHex`, `UpperHex`, `LowerExp`, `UpperExp`, `Octal`);
693/// * `#[wrapper(RangeOps)]` will derive all index traits working with ranges
694///   (`IndexRange`, `IndexTo`, `IndexFrom`, `IndexInclusive`,
695///   `IndexToInclusive`, `IndexFull`);
696/// * `#[wrapper(MathOps)]` will derive all arithmetic operations (`Neg`, `Add`,
697///   `Sub`, `Mul`, `Div`, `Rem`);
698/// * `#[wrapper(BoolOps)]` will derive all boolean operations (`Not`, `BitAnd`,
699///   `BitOr`, `BitXor`);
700/// * `#[wrapper(BitOps)]` will derive all boolean operations *and bit shifts*
701///   (`Not`, `BitAnd`, `BitOr`, `BitXor`, `Shl`, `Shr`).
702///
703/// Other traits, such as [`PartialEq`], [`Eq`], [`PartialOrd`], [`Ord`],
704/// [`Hash`] can be implemented using standard `#[derive]` attribute in the
705/// same manner as [`Default`], [`Debug`] and [`From`]
706///
707/// # Example
708///
709/// Simple wrapper:
710/// ```
711/// # #[macro_use] extern crate amplify_derive;
712/// use amplify::Wrapper;
713///
714/// #[derive(Wrapper, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, From, Debug, Display)]
715/// #[display(inner)]
716/// #[wrapper(LowerHex, UpperHex, Octal)]
717/// #[wrapper(MathOps, BitOps)]
718/// struct Int64(i64);
719/// ```
720///
721/// More complex wrapper with multiple unnamed fields:
722/// ```
723/// # #[macro_use] extern crate amplify_derive;
724/// # use std::collections::HashMap;
725/// # use std::fmt::Debug;
726/// use std::marker::PhantomData;
727///
728/// use amplify::Wrapper;
729///
730/// #[derive(Clone, Wrapper, Default, From)]
731/// #[wrapper(Debug)]
732/// struct Wrapped<T, U>(
733///     #[wrap]
734///     #[from]
735///     HashMap<usize, Vec<U>>,
736///     PhantomData<T>,
737/// )
738/// where U: Sized + Clone + Debug;
739///
740/// let w = Wrapped::<(), u8>::default();
741/// assert_eq!(w.into_inner(), HashMap::<usize, Vec<u8>>::default());
742/// ```
743///
744/// Wrappers for indexable types
745/// ```
746/// # #[macro_use] extern crate amplify_derive;
747/// use amplify::Wrapper;
748///
749/// #[derive(Wrapper, From)]
750/// #[wrapper(Index, RangeOps)]
751/// struct VecNewtype(Vec<u8>);
752/// ```
753#[proc_macro_derive(Wrapper, attributes(wrap, wrapper, amplify_crate))]
754pub fn derive_wrapper(input: TokenStream) -> TokenStream {
755    let derive_input = parse_macro_input!(input as DeriveInput);
756    wrapper::inner(derive_input)
757        .unwrap_or_else(|e| e.to_compile_error())
758        .into()
759}
760
761/// Derives [`WrapperMut`] and allows deriving other traits accessing the
762/// wrapped type which require mutable access to the inner type. Requires that
763/// the type already implements `amplify::Wrapper`.
764///
765/// Supports automatic implementation of the following traits:
766/// * `amplify::WrapperMut`
767/// * [`AsMut`]
768/// * [`core::borrow::BorrowMut`]
769/// You may skip `AsMut` and `BorrowMut` implementations with
770/// `#[wrapper_mut(NoRefs)]`.
771///
772/// You can implement additional derives, it they are implemented for the
773/// wrapped type, using `#[wrapper()]` proc macro:
774/// 1. Reference access to the inner type:
775///    * `DerefMut` for implementing [`core::ops::DerefMut`]
776///    * `AsSliceMut` for implementing [`AsMut`]`<[u8]>`
777///    * `BorrowSliceMut` for implementing
778///      [`core::borrow::BorrowMut`]`<[Self::Inner]>`
779/// 2. Indexed access to the inner type:
780///    * `IndexMut` for implementing [`core::ops::IndexMut`]`<usize>`
781///    * `IndexRangeMut` for implementing
782///      [`core::ops::IndexMut`]`<`[`core::ops::Range`]`<usize>>`
783///    * `IndexToMut` for implementing
784///      [`core::ops::IndexMut`]`<`[`core::ops::RangeTo`]`<usize>>`
785///    * `IndexFromMut` for implementing
786///      [`core::ops::IndexMut`]`<`[`core::ops::RangeFrom`]`<usize>>`
787///    * `IndexInclusiveMut` for implementing
788///      [`core::ops::IndexMut`]`<`[`core::ops::RangeInclusive`]`<usize>>`
789///    * `IndexToInclusiveMut` for implementing
790///      [`core::ops::IndexMut`]`<`[`core::ops::RangeToInclusive`]`<usize>>`
791///    * `IndexFullMut` for implementing
792///      [`core::ops::IndexMut`]`<`[`core::ops::RangeFrom`]`<usize>>`
793/// 3. Arithmetic operations:
794///    * `AddAssign` for implementing [`core::ops::AddAssign`]
795///    * `SubAssign` for implementing [`core::ops::SubAssign`]
796///    * `MulAssign` for implementing [`core::ops::MulAssign`]
797///    * `DivAssign` for implementing [`core::ops::DivAssign`]
798///    * `RemAssign` for implementing [`core::ops::RemAssign`]
799/// 4. Boolean and bit-wise operations:
800///    * `BitAndAssign` for implementing [`core::ops::BitAndAssign`]
801///    * `BitOrAssign` for implementing [`core::ops::BitOrAssign`]
802///    * `BitXorAssign` for implementing [`core::ops::BitXorAssign`]
803///    * `ShlAssign` for implementing [`core::ops::ShlAssign`]
804///    * `ShrAssign` for implementing [`core::ops::ShrAssign`]
805///
806/// There are shortcuts for derivations:
807/// * `#[wrapper(RangeMut)]` will derive all index traits working with ranges
808///   (`IndexRangeMut`, `IndexToMut`, `IndexFromMut`, `IndexInclusiveMut`,
809///   `IndexToInclusiveMut`, `IndexFullMut`);
810/// * `#[wrapper(MathAssign)]` will derive all arithmetic operations
811///   (`AddAssign`, `SubAssign`, `MulAssign`, `DivAssign`, `RemAssign`);
812/// * `#[wrapper(BoolAssign)]` will derive all boolean operations
813///   (`BitAndAssign`, `BitOrAssign`, `BitXorAssign`);
814/// * `#[wrapper(BitAssign)]` will derive all boolean operations *and bit
815///   shifts* (`BitAndAssign`, `BitOrAssign`, `BitXorAssign`, `ShlAssign`,
816///   `ShrAssign`);
817///
818/// # Example
819///
820/// ```
821/// # #[macro_use] extern crate amplify_derive;
822/// use amplify::{Wrapper, WrapperMut};
823///
824/// #[derive(
825///     Wrapper, WrapperMut, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, From, Debug,
826///     Display
827/// )]
828/// #[display(inner)]
829/// #[wrapper(NumberFmt, MathOps, BoolOps, FromStr)]
830/// #[wrapper_mut(MathAssign, BitAssign)]
831/// struct Int64(i64);
832/// ```
833#[proc_macro_derive(WrapperMut, attributes(wrap, wrapper_mut, amplify_crate))]
834pub fn derive_wrapper_mut(input: TokenStream) -> TokenStream {
835    let derive_input = parse_macro_input!(input as DeriveInput);
836    wrapper::inner_mut(derive_input)
837        .unwrap_or_else(|e| e.to_compile_error())
838        .into()
839}