1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
17#[serde(try_from = "String", into = "String")]
18pub struct ID(uuid::Uuid);
19impl ID {
20 pub fn new() -> Self {
29 Self(uuid::Uuid::new_v4())
30 }
31}
32impl Default for ID {
33 fn default() -> Self {
34 Self::new()
35 }
36}
37impl TryFrom<String> for ID {
38 type Error = uuid::Error;
39 fn try_from(value: String) -> Result<Self, Self::Error> {
54 value.parse()
55 }
56}
57
58impl core::str::FromStr for ID {
59 type Err = uuid::Error;
60
61 fn from_str(s: &str) -> Result<Self, Self::Err> {
76 Ok(ID(uuid::Uuid::parse_str(s)?))
77 }
78}
79impl core::fmt::Display for ID {
80 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
81 write!(f, "{}", self.0)
82 }
83}
84impl From<ID> for String {
85 fn from(value: ID) -> Self {
86 value.to_string()
87 }
88}
89impl core::ops::Deref for ID {
90 type Target = uuid::Uuid;
91
92 fn deref(&self) -> &Self::Target {
93 &self.0
94 }
95}
96#[cfg(test)]
97mod tests {
98 use super::*;
99 use core::ops::Deref;
100
101 #[test]
102 fn test_id_creation() {
103 let id = ID::new();
104 let id_str: String = id.into();
105
106 let parsed = ID::try_from(id_str.clone()).unwrap();
108 assert_eq!(id, parsed);
109
110 assert_eq!(id.to_string(), id_str);
112 }
113
114 #[test]
115 fn test_new_id() {
116 let id = ID::new();
117 assert!(uuid::Uuid::parse_str(&id.to_string()).is_ok());
118 }
119
120 #[test]
121 fn test_id_conversion() {
122 let id = ID::new();
123 let id_string = String::from(id);
124 let converted_id = ID::try_from(id_string.clone()).unwrap();
125 assert_eq!(id, converted_id);
126 assert_eq!(id.to_string(), id_string);
127 }
128
129 #[test]
130 fn test_invalid_id() {
131 let result = ID::try_from("not-a-uuid".to_string());
132 assert!(result.is_err());
133 }
134
135 #[test]
136 fn test_id_deref() {
137 let id = ID::new();
138 let uuid: &uuid::Uuid = id.deref();
139 assert_eq!(uuid.to_string(), id.to_string());
140 }
141
142 #[test]
143 fn test_id_display() {
144 let id = ID::new();
145 let uuid_string = id.0.to_string();
146 assert_eq!(id.to_string(), uuid_string);
147 }
148}