| Crates.io | tagged-id |
| lib.rs | tagged-id |
| version | 0.3.0 |
| created_at | 2024-08-26 16:53:46.184779+00 |
| updated_at | 2024-09-06 13:31:42.638099+00 |
| description | A zero-cost wrapper adding type-safety to resource identifiers. |
| homepage | https://github.com/kamek-pf/tagged-id |
| repository | https://github.com/kamek-pf/tagged-id |
| max_upload_size | |
| id | 1352416 |
| size | 21,332 |
tagged-idA zero-cost wrapper adding type-safety to resource identifiers.
This solves two problems:
Foo and Bar both being identified by a i32 for instance), they might be swapped by mistake in application code. The compiler cannot help you with this, but it is of course incorrect.use tagged_id::{Id, Identify};
#[derive(Id)] // note the derive macro
#[tagged_id(i32)] // this attribute specifies the underlying type
struct Foo {
id: Id<Foo>, // id is a i32
some_field: String,
}
struct Bar {
id: Id<Bar>, // id is also a i32, see impl below
some_value: i32,
}
// This is what the derive macro generates
impl Identify for Bar {
type InnerId = i32;
}
fn main() {
let foo_id: Id<Foo> = Id::new(42);
let bar_id: Id<Bar> = Id::new(42);
// This does not compile since the tags are different.
assert_eq!(foo_id, bar_id);
}
Id<T> inherits relevant core trait implementations of the inner type. For instance, if InnerId is Copy, then Id<T> is also Copy.
Id<T> is just a newtype wrapper of the inner type with a trait bound, which makes it a zero cost abstraction.
derive: Enable the derive macro, this feature is enabled by default.smartstring: Enable From<&str> instance converting to a CompactString. When disabled, an instance for String is enabled instead.uuid: Enable From<Uuid> instance for convenience.serde: Enable serde support for tagged-id and dependencies that support it like smartstring.sqlx-{postgres,mysql,sqlite}: Enable Encode and Decode instances for transparent use with the corresponding sqlx backend.