1use crate::prelude::*;
8use ::uuid::{Builder, Uuid as Inner, Variant, Version};
9
10#[derive(
12 Clone, Copy, Default, Deserialize, Eq, From, FromStr, Hash, Ord, PartialEq, PartialOrd, Serialize,
13)]
14#[serde(transparent)]
15pub struct Uuid(Inner);
16
17impl Uuid {
18 pub const fn nil() -> Self {
20 Self(Inner::nil())
21 }
22
23 pub fn is_nil(&self) -> bool {
25 self.0.is_nil()
26 }
27
28 pub fn new() -> Self {
30 random()
31 }
32
33 pub fn as_bytes(&self) -> &[u8] {
35 self.0.as_bytes()
36 }
37
38 pub fn to_u128(&self) -> u128 {
40 self.0.as_u128()
41 }
42}
43
44impl Random for Uuid {
47 fn random_with(rng: &mut random::Rng) -> Self {
48 let mut bytes = [0u8; 16];
49
50 rng.fill_bytes(&mut bytes);
51
52 let uuid =
53 Builder::from_bytes(bytes).set_variant(Variant::RFC4122).set_version(Version::Random).build();
54
55 Self(uuid)
56 }
57}
58
59macro_rules! impl_fmt {
62 ($ty:ident) => {
63 impl fmt::$ty for Uuid {
64 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65 fmt::$ty::fmt(&self.0, f)
66 }
67 }
68 };
69}
70
71impl_fmt!(Debug);
72impl_fmt!(Display);
73impl_fmt!(LowerHex);
74impl_fmt!(UpperHex);
75
76cfg_if! {
79 if #[cfg(feature = "postgres")] {
80 use postgres_types as pg;
81
82 impl<'a> pg::FromSql<'a> for Uuid {
83 fn from_sql(ty: &pg::Type, raw: &'a [u8]) -> Result<Self, Box<dyn Error + Sync + Send>>{
84 Ok(Self(pg::FromSql::from_sql(ty, raw)?))
85 }
86
87 fn accepts(ty: &pg::Type) -> bool {
88 <Inner as pg::FromSql>::accepts(ty)
89 }
90 }
91
92 impl pg::ToSql for Uuid {
93 fn to_sql(&self, ty: &pg::Type, out: &mut bytes::BytesMut) -> Result<pg::IsNull, Box<dyn Error + Sync + Send>>
94 where
95 Self: Sized,
96 {
97 self.0.to_sql(ty, out)
98 }
99
100 fn accepts(ty: &pg::Type) -> bool
101 where
102 Self: Sized,
103 {
104 <Inner as pg::ToSql>::accepts(ty)
105 }
106
107 fn to_sql_checked(&self, ty: &pg::Type, out: &mut bytes::BytesMut) -> Result<pg::IsNull, Box<dyn Error + Sync + Send>> {
108 self.0.to_sql_checked(ty, out)
109 }
110 }
111 }
112}