1
2use std::str::FromStr;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8pub struct UuidStr {
9 bytes: [u8; 36],
10}
11
12impl Default for UuidStr {
13 fn default() -> Self {
14 Self {
15 bytes: *b"00000000-0000-0000-0000-000000000000",
16 }
17 }
18}
19
20impl UuidStr {
21 pub fn new() -> Self {
22 Self::default()
23 }
24
25 pub fn new_v4() -> Self {
26 let uuid = uuid::Uuid::new_v4();
27 Self::from(&uuid)
28 }
29
30 pub fn bytes(&self) -> [u8; 36] {
31 self.bytes
32 }
33}
34
35impl AsRef<str> for UuidStr {
36 fn as_ref(&self) -> &str {
37 std::str::from_utf8(&self.bytes).unwrap()
38 }
39}
40
41impl std::fmt::Display for UuidStr {
42 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43 f.write_str(self.as_ref())
44 }
45}
46
47impl FromStr for UuidStr {
48 type Err = uuid::Error;
49
50 fn from_str(s: &str) -> Result<Self, Self::Err> {
51 let uuid = uuid::Uuid::parse_str(s)?;
52 Ok(Self::from(&uuid))
53 }
54}
55
56impl std::ops::Deref for UuidStr {
57 type Target = str;
58
59 fn deref(&self) -> &Self::Target {
60 self.as_ref()
61 }
62}
63
64impl std::convert::TryFrom<&str> for UuidStr {
65 type Error = uuid::Error;
66
67 fn try_from(s: &str) -> Result<Self, Self::Error> {
68 Self::from_str(s)
69 }
70}
71
72impl std::convert::TryFrom<String> for UuidStr {
73 type Error = uuid::Error;
74
75 fn try_from(s: String) -> Result<Self, Self::Error> {
76 Self::from_str(&s)
77 }
78}
79
80impl AsRef<[u8]> for UuidStr {
81 fn as_ref(&self) -> &[u8] {
82 &self.bytes
83 }
84}
85
86impl From<&uuid::Uuid> for UuidStr {
87 fn from(uuid: &uuid::Uuid) -> Self {
88 let str = uuid.as_hyphenated().to_string().to_ascii_lowercase();
89 let bytes = str.as_bytes();
90 assert_eq!(bytes.len(), 36);
91 let mut uuid_str = Self::default();
92 uuid_str.bytes.copy_from_slice(bytes);
93 uuid_str
94 }
95}
96
97impl From<uuid::Uuid> for UuidStr {
98 fn from(uuid: uuid::Uuid) -> Self {
99 Self::from(&uuid)
100 }
101}
102
103
104#[cfg(test)]
105mod tests {
106 use super::*;
107
108 #[test]
109 fn default() {
110 let default_uuid = UuidStr::default();
111 let default_str: &str = default_uuid.as_ref();
112 assert_eq!(default_str, "00000000-0000-0000-0000-000000000000");
113 }
114
115 #[test]
116 fn v4() {
117 let uuid = UuidStr::new_v4();
118 let bytes: &[u8] = uuid.as_ref();
119 assert_eq!(bytes.len(), 36);
120 let maybe_uuid = uuid::Uuid::parse_str(uuid.as_ref());
121 assert!(maybe_uuid.is_ok());
122 }
123}