type_uuid/
lib.rs

1//! This crate provides a way to specify a stable, unique identifier for Rust types.
2//!
3//! # Assigning UUIDs to Types
4//!
5//! This crate provides the [`TypeUuid`] trait, which defines a single const item
6//! `UUID`. This value is a byte array containing the raw bytes of the UUID for the
7//! type.
8//!
9//! You will have to manually specify the UUID for any type implementing
10//! [`TypeUuid`], but this crate provides a custom derive to make that easy to do:
11//!
12//! ```
13//! use type_uuid::TypeUuid;
14//!
15//! #[derive(TypeUuid)]
16//! #[uuid = "d4adfc76-f5f4-40b0-8e28-8a51a12f5e46"]
17//! struct MyType;
18//! ```
19//!
20//! While the derive handles the tedious work of converting the UUID into a byte
21//! array suitable for use with the [`TypeUuid`] trait, you'll still need to
22//! generate a valid UUID in order to assign it to your type. To do so, we
23//! recommend using https://www.uuidgenerator.net, which provides a quick way
24//! generate new UUIDs that you can paste into your code.
25//!
26//! [`TypeUuid`]: ./trait.TypeUuid.html
27
28#[doc(hidden)]
29pub use type_uuid_derive::*;
30
31#[cfg(feature = "amethyst")]
32pub mod amethyst_types;
33
34/// A 128-bit (16 byte) buffer containing the ID.
35///
36/// This is meant to match the [`Bytes` type defined in the uuid crate][bytes].
37/// Logically it's meant to be equivalent to using a `u128` to represent the
38/// UUID's numeric value, but specifying it as a byte array allows us to avoid
39/// endianness issues.
40///
41/// [bytes]: https://docs.rs/uuid/0.7/uuid/type.Bytes.html
42pub type Bytes = [u8; 16];
43
44/// Provides a statically defined UUID for a Rust type.
45///
46/// # Examples
47///
48/// This crate provides a custom derive that allows you to specify a UUID as
49/// a human-readable string. This is the recommended way to implement `TypeUuid`
50/// for your types. You can use https://www.uuidgenerator.net to generate
51/// random UUIDs to use with the derive.
52///
53/// ```
54/// use type_uuid::TypeUuid;
55///
56/// #[derive(TypeUuid)]
57/// #[uuid = "d4adfc76-f5f4-40b0-8e28-8a51a12f5e46"]
58/// struct MyType;
59/// ```
60pub trait TypeUuid {
61    const UUID: Bytes;
62}
63
64/// Allows the TypeUuid constants to be retrieved via a trait object.
65///
66/// This trait is sealed and cannot be implemented outside of the type-uuid
67/// codebase. It is implemented automatically for all types that implement
68/// [`TypeUuid`], which you should implement instead.
69///
70/// [`TypeUuid`]: ./trait.TypeUuid.html
71pub trait TypeUuidDynamic: private::Sealed {
72    fn uuid(&self) -> Bytes;
73}
74
75impl<T: TypeUuid> TypeUuidDynamic for T {
76    fn uuid(&self) -> Bytes {
77        Self::UUID
78    }
79}
80
81mod private {
82    pub trait Sealed {}
83
84    impl<T: super::TypeUuid> Sealed for T {}
85}
86
87// Implement `TypeUuid` for primitive types and types defined in the standard library.
88external_type_uuid!(bool, "abea8c1e-6910-43e4-b579-9ef1b5a95226");
89external_type_uuid!(isize, "0d3b0c08-45ff-43f4-a145-b2bdef69d1d2");
90external_type_uuid!(i8, "92fd5f7b-2102-46cb-9b1b-662df636625a");
91external_type_uuid!(i16, "a02dfda1-8603-4d69-818a-1e1c47b154b6");
92external_type_uuid!(i32, "6dd1ba7e-fa8b-4aa1-ac22-c28773798975");
93external_type_uuid!(i64, "3103622f-fdfa-4ae3-8ede-67b56bd332fd");
94external_type_uuid!(usize, "1d4562ce-b27d-4e99-af44-a40aca248c2e");
95external_type_uuid!(u8, "b0fe47a9-fd37-41c6-b2ab-bed5d385ccde");
96external_type_uuid!(u16, "3ad2a84b-c5a6-414c-8628-75613e11e67e");
97external_type_uuid!(u32, "f6cc80b8-94e8-4c05-80b1-a8fbbaeb67af");
98external_type_uuid!(u64, "da9a3e45-516c-4412-87d2-96ea17bebd21");
99external_type_uuid!(i128, "0dbb7b33-9f27-4b3f-aebc-11426c464323");
100external_type_uuid!(u128, "46eaab86-9268-4e98-ac9f-76eb71a1f0b4");
101external_type_uuid!(f32, "5b1d1734-9fcc-43e7-8cc6-452ba16ff1fd");
102external_type_uuid!(f64, "76b2ebf4-cd06-41de-96dc-2f402ffa46b2");
103external_type_uuid!(char, "9786a9f4-1195-4dd1-875d-3e469454d9c4");
104external_type_uuid!(str, "2d07a3d2-d793-44f2-bb28-08c445b164c9");
105external_type_uuid!(String, "7edbc10a-2147-499c-af9a-498723c7b35f");
106external_type_uuid!(std::ffi::CStr, "f8ca0716-c80a-4aca-a2f1-bdef739d5688");
107external_type_uuid!(std::ffi::CString, "d26a39da-d0e2-46b1-aeab-481fe57d0f23");
108external_type_uuid!(std::ffi::OsStr, "fb7f1478-03fc-4884-b710-977c8bf9fa8b");
109external_type_uuid!(std::ffi::OsString, "38485fce-f5d0-48df-b5cb-98e510c26a8d");
110external_type_uuid!(std::num::NonZeroU8, "284b98ec-ecb5-463c-9744-23b8669c5553");
111external_type_uuid!(std::num::NonZeroU16, "38f030e4-6046-45c9-96b4-1830b1aa3f35");
112external_type_uuid!(std::num::NonZeroU32, "b32f7cc7-2841-48b3-8d8e-760414b4c4ab");
113external_type_uuid!(std::num::NonZeroU64, "b43c6dad-6608-4f02-817a-8eac8c6345cb");
114external_type_uuid!(std::time::Duration, "449a4224-4665-47ce-88a2-8d0310d20572");
115external_type_uuid!(
116    std::time::SystemTime,
117    "b8dfc518-faf7-4590-91ba-82acd78b1685"
118);
119external_type_uuid!(std::net::IpAddr, "a3c248b7-94e1-4d4a-8b7e-fd1915f4c81b");
120external_type_uuid!(std::net::Ipv4Addr, "a62542a2-6a38-4980-9467-f093bb546140");
121external_type_uuid!(std::net::Ipv6Addr, "a6ba4f16-f436-4ae2-ae62-69dd08150b33");
122external_type_uuid!(std::net::SocketAddr, "fe76891f-3e0a-49f7-b32e-14fc11768844");
123external_type_uuid!(
124    std::net::SocketAddrV4,
125    "e951fa30-50d9-4832-8bc9-c49c06037697"
126);
127external_type_uuid!(
128    std::net::SocketAddrV6,
129    "8840455b-ad6c-41ae-8694-e50873d952c4"
130);
131external_type_uuid!(std::path::Path, "72b02282-6efe-4392-9d9c-467b23ca8c83");
132external_type_uuid!(std::path::PathBuf, "d6db3123-4c95-45de-a28f-5a48d574b9c4");
133
134#[allow(dead_code)]
135type Unit = ();
136external_type_uuid!(Unit, "03748d1a-0d0c-472f-9fdd-424856157064");
137
138#[cfg(test)]
139mod test {
140    use crate::*;
141
142    /// Verifies that `TypeUuidDynamic` can be instantiated as a trait object.
143    #[test]
144    fn type_uuid_trait_object() {
145        let trait_object = Box::new(()) as Box<TypeUuidDynamic>;
146        println!("UUID for (): {:#X?}", trait_object.uuid());
147    }
148}