1use std::ops::Deref;
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
19#[serde(try_from = "String", into = "String")]
20pub struct ID(uuid::Uuid);
21impl ID {
22 pub fn new() -> Self {
31 Self(uuid::Uuid::new_v4())
32 }
33}
34impl Default for ID {
35 fn default() -> Self {
36 Self::new()
37 }
38}
39impl TryFrom<String> for ID {
40 type Error = uuid::Error;
41 fn try_from(value: String) -> Result<Self, Self::Error> {
56 Ok(ID(uuid::Uuid::parse_str(&value)?))
57 }
58}
59impl core::fmt::Display for ID {
60 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61 write!(f, "{}", self.0)
62 }
63}
64impl From<ID> for String {
65 fn from(value: ID) -> Self {
66 value.to_string()
67 }
68}
69impl Deref for ID {
70 type Target = uuid::Uuid;
71
72 fn deref(&self) -> &Self::Target {
73 &self.0
74 }
75}
76#[cfg(test)]
77mod tests {
78 use super::*;
79
80 #[test]
81 fn test_id_creation() {
82 let id = ID::new();
83 let id_str: String = id.into();
84
85 let parsed = ID::try_from(id_str.clone()).unwrap();
87 assert_eq!(id, parsed);
88
89 assert_eq!(id.to_string(), id_str);
91 }
92
93 #[test]
94 fn test_new_id() {
95 let id = ID::new();
96 assert!(uuid::Uuid::parse_str(&id.to_string()).is_ok());
97 }
98
99 #[test]
100 fn test_id_conversion() {
101 let id = ID::new();
102 let id_string = String::from(id);
103 let converted_id = ID::try_from(id_string.clone()).unwrap();
104 assert_eq!(id, converted_id);
105 assert_eq!(id.to_string(), id_string);
106 }
107
108 #[test]
109 fn test_invalid_id() {
110 let result = ID::try_from("not-a-uuid".to_string());
111 assert!(result.is_err());
112 }
113
114 #[test]
115 fn test_id_deref() {
116 let id = ID::new();
117 let uuid: &uuid::Uuid = id.deref();
118 assert_eq!(uuid.to_string(), id.to_string());
119 }
120
121 #[test]
122 fn test_id_display() {
123 let id = ID::new();
124 let uuid_string = id.0.to_string();
125 assert_eq!(id.to_string(), uuid_string);
126 }
127}