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}