# Newtypes
The `newtypes` crate is meant to ease the implementation of the
[Newtype](https://rust-unofficial.github.io/patterns/patterns/behavioural/newtype.html)
pattern while trying to make as few assumptions as possible.
## `newtype!` Macro
The `newtype!` macro creates a barebones newtype by wrapping an inner type with
a struct, and, if possible, implementing some extra traits for it.
By default, all declared structs have visibility `pub`.
```rust
use newtypes::newtype;
newtype!(NewTypeName, underlying_type);
// In case we want to automatically derive traits (like serde's
// Serialize or Deserialize):
newtype!(NewTypeName, underlying_type; Trait1, ..., TraitN);
```
Example:
```rust
use newtypes::newtype;
use serde::{Deserialize, Serialize}
newtype!(UserId, u32);
newtype!(GroupId, u32; Serialize, Deserialize);
```
### Implemented traits
- For all:
- [`Debug`](https://doc.rust-lang.org/std/fmt/trait.Debug.html)
- [`Into<inner_type>`](https://doc.rust-lang.org/std/convert/trait.Into.html)
- For integers:
- [`Clone`](https://doc.rust-lang.org/std/clone/trait.Clone.html)
- [`Copy`](https://doc.rust-lang.org/std/marker/trait.Copy.html)
- [`Hash`](https://doc.rust-lang.org/std/hash/trait.Hash.html)
- [`PartialEq`](https://doc.rust-lang.org/std/cmp/trait.PartialEq.html)
- [`Eq`](https://doc.rust-lang.org/std/cmp/trait.Eq.html)
- For floating point numbers:
- [`Clone`](https://doc.rust-lang.org/std/clone/trait.Clone.html)
- [`Copy`](https://doc.rust-lang.org/std/marker/trait.Copy.html)
- [`PartialEq`](https://doc.rust-lang.org/std/cmp/trait.PartialEq.html)
- For `String`:
- [`Clone`](https://doc.rust-lang.org/std/clone/trait.Clone.html)
- [`Hash`](https://doc.rust-lang.org/std/hash/trait.Hash.html)
- [`PartialEq`](https://doc.rust-lang.org/std/cmp/trait.PartialEq.html)
- [`Eq`](https://doc.rust-lang.org/std/cmp/trait.Eq.html)
> **IMPORTANT:** The inner value is private. If there are no constraints on the
> inner value, then we can rely on [`newtype_from!`](#newtype_from-macro) macro
> to implement the `From` and `FromStr` traits for us.
>
> Otherwise we can choose to implement
> [`From`](https://doc.rust-lang.org/std/convert/trait.From.html),
> [`FromStr`](https://doc.rust-lang.org/std/str/trait.FromStr.html) and
> [`TryFrom`](https://doc.rust-lang.org/std/convert/trait.TryFrom.html)
> manually.
## `newtype_ord!` Macro
The `newtype_ord!` macro extends the functionality provided with
[`newtype!`](#newtype-macro) by implementing the
[`PartialOrd`](https://doc.rust-lang.org/std/cmp/trait.PartialOrd.html) and
[`Ord`](https://doc.rust-lang.org/std/cmp/trait.Ord.html) traits
(when possible).
Example:
```rust
use newtypes::newtype_ord;
use serde::{Deserialize, Serialize}
newtype_ord!(Rank, u16);
newtype_ord!(TicketNumber, u16; Serialize, Deserialize);
```
> **NOTE:** It only works for integers, floating point numbers, and `String`.
## `newtype_unit!` Macro
The `newtype_unit!` macro extends the functionality provided with
[`newtype_ord!`](#newtype_ord-macro) by implementing the
[`Add`](https://doc.rust-lang.org/std/ops/trait.Add.html),
[`Sub`](https://doc.rust-lang.org/std/ops/trait.Sub.html),
[`AddAssign`](https://doc.rust-lang.org/std/ops/trait.AddAssign.html),
[`SubAssign`](https://doc.rust-lang.org/std/ops/trait.SubAssign.html), and
[`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) traits.
Example:
```rust
use newtypes::newtype_unit;
use serde::Deserialize;
newtype_unit!(Weight, f32);
newtype_unit!(Length, f32; Deserialize);
```
> **NOTE:** It only works for integers and floating point numbers.
> **NOTE:** It does not implement arithmetic operations beyond addition and
> subtraction. Doing that properly would require a more complex library focused
> on dealing with "units" (example: multiplying lengths gives us an area).
## `newtype_from!` Macro
The macro `newtype_from!` implements the `From` and `FromStr` traits for us
in case it's possible.
It has to be used in combination with one of the other ones
([`newtype!`](#newtype-macro), [`newtype_ord!`](#newtype_ord-macro), or
[`newtype_unit!`](#newtype_unit-macro)).
Example:
```rust
use newtypes::{newtype, newtype_from};
newtype!(Weight, f32);
newtype_from!(Weight, f32);
```
> **NOTE:** It only works for integers, floating point numbers, and `String`.