Crate newtype_derive_2018[−][src]
Expand description
This crate provides several macros for deriving implementations of various traits for “newtype”
wrappers (i.e. tuple structs with a single element).
That is, given a tuple struct with exactly one field (e.g. struct Buckets(i32)
),
these macros will derive “obvious” implementations of traits such as
Add
, Neg
, Index
, Deref
, etc.
All of these macros are designed to be used with the
macro-attr-2018
crate,
though they can be used independent of it.
Example
Create a simple integer wrapper with some arithmetic operators:
use macro_attr_2018::macro_attr; use newtype_derive_2018::*; macro_attr! { #[derive(NewtypeAdd!, NewtypeMul!(i32))] pub struct Happy(pub i32); } // Let's add some happy little ints. let a = Happy(6); let b = Happy(7); let c = (a + b) * 3; let d: i32 = c.0; assert_eq!(d, 39);
Create a “deref-transparent” wrapper around a smart pointer:
use macro_attr_2018::macro_attr; use newtype_derive_2018::*; macro_attr! { #[derive(NewtypeDeref!, NewtypeDerefMut!)] pub struct I32Array(Vec<i32>); } let mut arr = I32Array(vec![1, 2, 3]); assert_eq!(&*arr, &[1, 2, 3]);
Overview
This crate provides macros to derive implementations of the following traits for newtype structs:
- binary arithmetic operators:
Add
,BitAnd
,BitOr
,BitXor
,Div
,Mul
,Rem
,Sub
,Shl
,Shr
, plus the corresponding*Assign
traits. - unary arithmetic operators:
Neg
,Not
. - other operators:
Deref
,DerefMut
,Index
,IndexMut
. - formatting:
Binary
,Debug
,Display
,LowerExp
,LowerHex
,Octal
,Pointer
,UpperExp
,UpperHex
.
All of these macros are named Newtype$Trait
.
All these macros support generic newtype structs. By default, no bounds for generic parameters generated. To add constraints, they should wrap macros arguments (if any) within parenthesis, and add where clause after it. For example:
macro_attr! { #[derive(NewtypeAdd!(where T: Add<Output=T>))] #[derive(NewtypeAdd!((&self, &Self) where T: Add<Output=T>))] #[derive(NewtypeSub!((*) where T: Sub<Output=T>))] pub struct Dummy<T: Copy>(T); }
Binary Arithmetic Operators
Each of the binary arithmetic operators accept several deriving forms.
To use Add
on a struct T
as an example:
Attribute | Generated implementation |
---|---|
NewtypeAdd | impl Add<T, Output=T> for T |
NewtypeAdd(&self) | impl<'a> Add<T, Output=T> for &'a T |
NewtypeAdd(U) | impl Add<U, Output=T> for T |
NewtypeAdd(&self, U) | impl<'a> Add<U, Output=T> for &'a T |
NewtypeAdd(*) | All four combinations of T and &T |
The *Assign
variants accept zero or one argument only. For example:
Attribute | Generated implementation |
---|---|
NewtypeAddAssign | impl AddAssign<T> for T |
NewtypeAddAssign(U) | impl Add<U> for T |
NewtypeAddAssign(*) | Implements for T and &T . |
In all cases, the implementation unwraps the newtype (where necessary), forwards to the wrapped value’s implementation, then re-wraps the result in the newtype.
Unary Arithmetic Operators
Each of the binary arithmetic operators accept several deriving forms.
To use Neg
on a struct T
as an example:
Attribute | Generated implementation |
---|---|
NewtypeNeg | impl Neg<Output=T> for T |
NewtypeNeg(&self) | impl<'a> Neg<Output=T> for &'a T |
NewtypeNeg(*) | Both of the above |
In all cases, the implementation unwraps the newtype, forwards to the wrapped value’s implementation, then re-wraps the result in the newtype.
Other Operators
NewtypeDeref
and NewtypeDerefMut
only support the argument-less form.
The call is forwarded to the wrapped value’s implementation.
NewtypeIndex
and NewtypeIndexMut
must be used as NewtypeIndex(usize)
,
where the argument is the type to use for indexing.
The call is forwarded to the wrapped value’s implementation.
Formatting
The deriving macros for the formatting traits in std::fmt
forward to the wrapped value’s implementation.
Using Without macro_attr!
Although designed to be used with
macro_attr!
,
all of the macros in this crate can be used without it.
The following:
use macro_attr_2018::macro_attr; use newtype_derive_2018::*; macro_attr! { #[derive(Copy, Clone, Debug, NewtypeAdd!, NewtypeAdd!(f32))] pub struct Meters(pub f32); }
can also be written as
use newtype_derive_2018::*; #[derive(Copy, Clone, Debug)] pub struct Meters(pub f32); NewtypeAdd! { () pub struct Meters(pub f32); } NewtypeAdd! { (f32) pub struct Meters(pub f32); }