# newtype-uuid
[](https://crates.io/crates/newtype-uuid)
[](https://docs.rs/newtype-uuid)
[](https://oxidecomputer.github.io/newtype-uuid/rustdoc/newtype_uuid/)
[](LICENSE-APACHE)
[](LICENSE-MIT)
A newtype wrapper around `Uuid`.
## Motivation
Many large systems use UUIDs as unique identifiers for various entities. However, the `Uuid`
type does not carry information about the kind of entity it identifies, which can lead to mixing
up different types of UUIDs at runtime.
This crate provides a wrapper type around `Uuid` that allows you to specify the kind of entity
the UUID identifies.
## Example
```rust
use newtype_uuid::{GenericUuid, TypedUuid, TypedUuidKind, TypedUuidTag};
// First, define a type that represents the kind of UUID this is.
enum MyKind {}
impl TypedUuidKind for MyKind {
fn tag() -> TypedUuidTag {
// Tags are required to be ASCII identifiers, with underscores
// and dashes also supported. The validity of a tag can be checked
// at compile time by assigning it to a const, like so:
const TAG: TypedUuidTag = TypedUuidTag::new("my_kind");
TAG
}
}
// Now, a UUID can be created with this kind.
let uuid: TypedUuid<MyKind> = "dffc3068-1cd6-47d5-b2f3-636b41b07084".parse().unwrap();
// The Display (and therefore ToString) impls still show the same value.
assert_eq!(uuid.to_string(), "dffc3068-1cd6-47d5-b2f3-636b41b07084");
// The Debug impl will show the tag as well.
assert_eq!(format!("{:?}", uuid), "dffc3068-1cd6-47d5-b2f3-636b41b07084 (my_kind)");
```
If you have a large number of UUID kinds, consider defining a macro for your purposes. An
example macro:
```rust
macro_rules! impl_typed_uuid_kind {
($($kind:ident => $tag:literal),* $(,)?) => {
$(
pub enum $kind {}
impl TypedUuidKind for $kind {
#[inline]
fn tag() -> TypedUuidTag {
const TAG: TypedUuidTag = TypedUuidTag::new($tag);
TAG
}
}
)*
};
}
// Invoke this macro with:
impl_typed_uuid_kind! {
Kind1 => "kind1",
Kind2 => "kind2",
}
```
## Implementations
In general, `TypedUuid` uses the same wire and serialization formats as `Uuid`. This means
that persistent representations of `TypedUuid` are the same as `Uuid`; `TypedUuid` is
intended to be helpful within Rust code, not across serialization boundaries.
- The `Display` and `FromStr` impls are forwarded to the underlying `Uuid`.
- If the `serde` feature is enabled, `TypedUuid` will serialize and deserialize using the same
format as `Uuid`.
- If the `schemars08` feature is enabled, `TypedUuid` will implement `JsonSchema` if the
corresponding `TypedUuidKind` implements `JsonSchema`.
To abstract over typed and untyped UUIDs, the `GenericUuid` trait is provided. This trait also
permits conversions between typed and untyped UUIDs.
## Dependencies
- The only required dependency is the `uuid` crate. Optional features may add further
dependencies.
## Features
- `default`: Enables default features in the newtype-uuid crate.
- `std`: Enables the use of the standard library. *Enabled by default.*
- `serde`: Enables serialization and deserialization support via Serde. *Not enabled by
default.*
- `v4`: Enables the `new_v4` method for generating UUIDs. *Not enabled by default.*
- `schemars08`: Enables support for generating JSON schemas via schemars 0.8. *Not enabled by
default.* Note that the format of the generated schema is **not currently part** of the stable
API, though we hope to stabilize it in the future.
- `proptest1`: Enables support for generating `proptest::Arbitrary` instances of UUIDs. *Not enabled by default.*
## Minimum supported Rust version (MSRV)
The MSRV of this crate is **Rust 1.60.** In general, this crate will follow the MSRV of the
underlying `uuid` crate.
Within the 1.x series, MSRV updates will be accompanied by a minor version bump. The MSRVs for
each minor version are:
* Version **1.0.x**: Rust 1.60.
* Version **1.1.x**: Rust 1.61. This permits `TypedUuid<T>` to have `const fn` methods.
* Version **1.2.x**: Rust 1.67, required by some dependency updates.
## Alternatives
- [`typed-uuid`](https://crates.io/crates/typed-uuid): generally similar, but with a few design
decisions that are different.
## License
This project is available under the terms of either the [Apache 2.0 license](LICENSE-APACHE) or the [MIT
license](LICENSE-MIT).