1 unstable release
0.1.0 | Mar 20, 2020 |
---|
#16 in #strong-typing
22KB
456 lines
Derive basic integer operations for newtype IDs.
License
id-derive
is distributed under the terms of both the MIT license and the
Apache License (Version 2.0).
See LICENSE-APACHE and LICENSE-MIT for details.
lib.rs
:
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);
Dependencies
~1.5MB
~37K SLoC