Expand description

This crate provides several macros for deriving implementations of various traits for “newtype” wrappers (i.e. tuple structs with a single non-zero sized element). That is, given a tuple struct with exactly one field (e.g. struct Buckets(i32)), (or exactly one field followed by any number of zero-sized fields) 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 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, add where clause to the end of macros arguments. 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:

AttributeGenerated implementation
NewtypeAddimpl 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:

AttributeGenerated implementation
NewtypeAddAssignimpl 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:

AttributeGenerated implementation
NewtypeNegimpl 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); }

Macros

Derives Add trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives Binary trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives BitAnd trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives BitOr trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives BitXor trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives Debug trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives Deref trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives DerefMut trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives Display trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives Div trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives Index trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives IndexMut trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives LowerExp trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives LowerHex trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives Mul trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives Neg trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives Not trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives Octal trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives Pointer trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives Rem trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives Shl trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives Shr trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives Sub trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives UpperExp trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).

Derives UpperHex trait implementation for newtype wrappers (i.e. tuple structs with a single non-zero sized element).