Expand description
The goal of this crate is to provide an easy newtype implementation for different types of strongly-typed identifiers.
§Motivation
Very often, I find myself utilizing many integer-based IDs. In effort to make it strongly typed, one typically uses a “newtype” pattern.
struct MyId(usize);
let id = MyId(1);
assert_eq!(id.0, 1);
assert_eq!(MyId(id.0 + 10).0, MyId(11).0);
Notice how you have to access the tuple element with .0
any time you want to perform any type
of operations on the actual integer. One could approach this by implementing Deref
trait but
this is strongly discouraged; see: Rust Docs,
API Guidelines.
This crate introduces a set of macros implementing certain operations on an ID.
§Examples
In the simplest case, you only need to a single derive Id
.
#[derive(Id, Debug, PartialEq, Copy, Clone)]
struct MyId(usize);
// Construct from the inner type.
let mut id = MyId::from(1);
// Construct inner type from `MyId`.
assert_eq!(usize::from(id), 1);
// Display.
assert_eq!(&id.to_string(), "1");
// Add two IDs or inner to ID.
assert_eq!(id + MyId(1), MyId(2));
assert_eq!(id + 1, MyId(2));
id += 1;
id += MyId(1);
assert_eq!(id, MyId(3));
// Subtract
assert_eq!(id - MyId(1), MyId(2));
assert_eq!(id - 1, MyId(2));
id -= 1;
id -= MyId(1);
assert_eq!(id, MyId(1));
// Multiply
assert_eq!(id * MyId(2), MyId(2));
assert_eq!(id * 2, MyId(2));
id *= 2;
id *= MyId(2);
assert_eq!(id, MyId(4));
// Divide
assert_eq!(id / MyId(2), MyId(2));
assert_eq!(id / 2, MyId(2));
id /= 2;
id /= MyId(2);
assert_eq!(id, MyId(1));
Alternatively, you may devine only a subset of available derives:
#[derive(Display, FromInner, IntoInner, Add, AddInner)]
struct MyId(usize);
Derive Macros§
- Add
- Implements
Add<Self>
. - AddAssign
- Implements
AddAssign<Self>
. - AddAssign
Inner - Implements
AddAssign<T>
whereT
is the type of identifier. - AddInner
- Implements
Add<T>
whereT
is the type of identifier. - Convert
- Equivalent to
derive(IntoInner, FromInner)
. - Display
- Implements
Display
. - Div
- Implements
Div<Self>
. - DivAssign
- Implements
DivAssign<Self>
. - DivAssign
Inner - Implements
DivAssign<T>
whereT
is the type of identifier. - DivInner
- Implements
Div<T>
whereT
is the type of identifier. - From
Inner - Implements
From<T>
whereT
is the type of identifier. - Id
- Implement all available traits.
- Into
Inner - Implements
From<Self>
forT
whereT
is the type of identifier. - Mul
- Implements
Mul<Self>
. - MulAssign
- Implements
MulAssign<Self>
. - MulAssign
Inner - Implements
MulAssign<T>
whereT
is the type of identifier. - MulInner
- Implements
Mul<T>
whereT
is the type of identifier. - Sub
- Implements
Sub<Self>
. - SubAssign
- Implements
SubAssign<Self>
. - SubAssign
Inner - Implements
SubAssign<T>
whereT
is the type of identifier. - SubInner
- Implements
Sub<T>
whereT
is the type of identifier.