5 releases
Uses old Rust 2015
0.1.6 | Jul 20, 2016 |
---|---|
0.1.4 | Jan 18, 2016 |
0.1.3 | Dec 1, 2015 |
0.1.2 | Sep 16, 2015 |
0.1.1 | Aug 16, 2015 |
#2351 in Rust patterns
22,681 downloads per month
Used in 183 crates
(24 directly)
42KB
948 lines
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
, From
, etc.
All of these macros are designed to be used with the custom_derive
crate, though they can be used independent of it.
Example
Create a simple integer wrapper with some arithmetic operators:
#[macro_use] extern crate custom_derive;
#[macro_use] extern crate newtype_derive;
custom_derive! {
#[derive(NewtypeFrom, NewtypeAdd, NewtypeMul(i32))]
pub struct Happy(i32);
}
// Let's add some happy little ints.
let a = Happy::from(6);
let b = Happy::from(7);
let c = (a + b) * 3;
let d: i32 = c.into();
assert_eq!(d, 39);
Create a "deref-transparent" wrapper around a type:
#[macro_use] extern crate custom_derive;
#[macro_use] extern crate newtype_derive;
custom_derive! {
#[derive(NewtypeFrom,
NewtypeDeref, NewtypeDerefMut,
NewtypeIndex(usize), NewtypeIndexMut(usize)
)]
pub struct I32Array(Vec<i32>);
}
let mut arr = I32Array::from(vec![1, 2, 3]);
arr.push(4);
arr[2] = 5;
assert_eq!(&**arr, &[1, 2, 5, 4]);
assert_eq!(arr.len(), 4);
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.
- Miscellaneous: From.
- Unstable: One, Product, Sum, Zero (requires the
std-unstable
feature).
All of these macros are named Newtype$Trait
.
None of these macros currently support generic newtype structs.
Binary Arithmetic Operators
Each of the binary arithmetic operators accept several deriving forms. To use Add
on a struct T
as an example:
NewtypeAdd
:impl Add<T, Output=T> for T
NewtypeAdd(&self)
:impl<'a> Add<&'a 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 ofT
and&T
The *Assign
variants accept zero or one argument only. For example:
NewtypeAddAssign
:impl AddAssign<T> for T
NewtypeAddAssign(&Self)
:impl<'a> Add<&'a T> for &'a T
NewtypeAddAssign(U)
:impl Add<U> for T
NewtypeAddAssign(*)
: Implements forT
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:
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, and implements the corresponding trait such that the newtype structure derefs to a pointer to the wrapped value.
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.
Miscellaneous
NewtypeFrom
implements std::convert::From
twice: once for converting from the wrapped type to the newtype, and once for converting from the newtype to the wrapped type.
NewtypeProduct
and NewtypeSum
optionally support specifying &Self
as an argument to generate an implementation that accepts an iterator of borrowed pointers (e.g. NewtypeSum(&Self)
).
Using Without custom_derive!
Although designed to be used with custom_derive!
, all of the macros in this crate can be used without it. The following:
custom_derive! {
#[derive(Copy, Clone, Debug, NewtypeFrom, NewtypeAdd, NewtypeAdd(f32))]
pub struct Meters(f32);
}
Can also be written as:
#[derive(Copy, Clone, Debug)]
pub struct Meters(f32);
NewtypeFrom! { () pub struct Meters(f32); }
NewtypeAdd! { () pub struct Meters(f32); }
NewtypeAdd! { (f32) pub struct Meters(f32); }
No runtime deps
~11KB