Lightweight newtypes without macros.
phantom-newtype
is a library that provides a simple way to define newtypes.
It's not a replacement for the newtype idiom but rather a nice addition to it that covers common use-cases.
Example: ```rust // Amount and Id are "kinds" of newtypes people commonly use. // Let's call them "archetypes". use phantom_newtype::{Amount, Id};
// CentUnit here is just a fresh type that should never be constructed.
// It allows us to forge a new type of amounts.
struct CentUnit;
type Cents = AmountCents
.
// Let's create another type of amounts.
// phantom-newtype is not a replacement for a powerful units library though.
struct YearUnit;
type Years = Amount
// Any type can be used as a tag, it's not necessary to always define new structs.
type UserId = IdId
.
struct User { id: UserId, name: String, balance: Cents, age: Years, }
impl User { fn new() -> Self { Self { id: UserId::from(1), name: "John".to_string(), balance: Cents::from(1000), age: Years::from(28), } } }
// Tags used in archetypes can be useful in generic code.
fn loadbyid
phantom-newtype
| Trait\Archetype | Amount<T, Repr>
| Id<T, Repr>
|
|-----------------|:-----------------:|:-------------:|
| Default
| ✘ | ✘ |
| Clone
| ✔ | ✔ |
| Copy
| ✔ | ✔ |
| Debug
| ✔ | ✔ |
| Display
| ✔ | ✔ |
| Eq
| ✔ | ✔ |
| Ord
| ✔ | ✔ |
| Hash
| ✔ | ✔ |
| From<Repr>
| ✔ | ✔ |
| Add
| ✔ (amounts) | ✘ |
| Sub
| ✔ (amounts) | ✘ |
| Mul
| ✔ (by a scalar) | ✘ |
| Div
| ✔ (by a scalar) | ✘ |
The approach taken by the library has some limitations due to design choices made by Rust:
phantom-newtype
.
Every combination of desired traits requires a new archetype.phantom-newtype
, every newtype inherits implementations of its representation (including Debug
and Display
).