reifydb_type/value/identity/
mod.rs1use std::{fmt, ops::Deref, str::FromStr};
5
6use serde::{Deserialize, Deserializer, Serialize, Serializer, de, de::Visitor};
7use uuid::Uuid;
8
9use crate::value::uuid::Uuid7;
10
11#[repr(transparent)]
13#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Ord, Eq, Hash, Default)]
14pub struct IdentityId(pub Uuid7);
15
16impl IdentityId {
17 pub fn generate() -> Self {
19 IdentityId(Uuid7::generate())
20 }
21
22 pub fn new(id: Uuid7) -> Self {
24 IdentityId(id)
25 }
26
27 pub fn value(&self) -> Uuid7 {
29 self.0
30 }
31
32 pub fn anonymous() -> Self {
35 let bytes = [
36 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37 ];
38 IdentityId(Uuid7(Uuid::from_bytes(bytes)))
39 }
40
41 pub fn root() -> Self {
44 let bytes = [
45 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
46 ];
47 IdentityId(Uuid7(Uuid::from_bytes(bytes)))
48 }
49
50 pub fn system() -> Self {
53 let bytes = [
54 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x7F, 0xFF, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
55 ];
56 IdentityId(Uuid7(Uuid::from_bytes(bytes)))
57 }
58
59 pub fn is_anonymous(&self) -> bool {
60 *self == Self::anonymous()
61 }
62
63 pub fn is_root(&self) -> bool {
64 *self == Self::root()
65 }
66
67 pub fn is_system(&self) -> bool {
68 *self == Self::system()
69 }
70
71 pub fn is_privileged(&self) -> bool {
73 self.is_root() || self.is_system()
74 }
75}
76
77impl Deref for IdentityId {
78 type Target = Uuid7;
79
80 fn deref(&self) -> &Self::Target {
81 &self.0
82 }
83}
84
85impl PartialEq<Uuid7> for IdentityId {
86 fn eq(&self, other: &Uuid7) -> bool {
87 self.0.eq(other)
88 }
89}
90
91impl From<Uuid7> for IdentityId {
92 fn from(id: Uuid7) -> Self {
93 IdentityId(id)
94 }
95}
96
97impl From<IdentityId> for Uuid7 {
98 fn from(identity_id: IdentityId) -> Self {
99 identity_id.0
100 }
101}
102
103impl fmt::Display for IdentityId {
104 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105 write!(f, "{}", self.0)
106 }
107}
108
109impl Serialize for IdentityId {
110 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
111 where
112 S: Serializer,
113 {
114 self.0.serialize(serializer)
115 }
116}
117
118impl<'de> Deserialize<'de> for IdentityId {
119 fn deserialize<D>(deserializer: D) -> Result<IdentityId, D::Error>
120 where
121 D: Deserializer<'de>,
122 {
123 struct Uuid7Visitor;
124
125 impl<'de> Visitor<'de> for Uuid7Visitor {
126 type Value = IdentityId;
127
128 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
129 formatter.write_str("a UUID version 7")
130 }
131
132 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
133 where
134 E: de::Error,
135 {
136 let uuid =
137 Uuid::from_str(value).map_err(|e| E::custom(format!("invalid UUID: {}", e)))?;
138
139 if uuid.get_version_num() != 7 {
140 return Err(E::custom(format!(
141 "expected UUID v7, got v{}",
142 uuid.get_version_num()
143 )));
144 }
145
146 Ok(IdentityId(Uuid7::from(uuid)))
147 }
148
149 fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
150 where
151 E: de::Error,
152 {
153 let uuid = Uuid::from_slice(value)
154 .map_err(|e| E::custom(format!("invalid UUID bytes: {}", e)))?;
155
156 if uuid.get_version_num() != 7 {
158 return Err(E::custom(format!(
159 "expected UUID v7, got v{}",
160 uuid.get_version_num()
161 )));
162 }
163
164 Ok(IdentityId(Uuid7::from(uuid)))
165 }
166 }
167
168 deserializer.deserialize_any(Uuid7Visitor)
169 }
170}
171
172#[cfg(test)]
173pub mod tests {
174 use super::*;
175
176 #[test]
177 fn test_identity_id_creation() {
178 let id = IdentityId::generate();
179 assert_ne!(id, IdentityId::default());
180 }
181
182 #[test]
183 fn test_identity_id_from_uuid7() {
184 let uuid = Uuid7::generate();
185 let id = IdentityId::from(uuid);
186 assert_eq!(id.value(), uuid);
187 }
188
189 #[test]
190 fn test_identity_id_display() {
191 let id = IdentityId::generate();
192 let display = format!("{}", id);
193 assert!(!display.is_empty());
194 }
195
196 #[test]
197 fn test_identity_id_equality() {
198 let uuid = Uuid7::generate();
199 let id1 = IdentityId::from(uuid);
200 let id2 = IdentityId::from(uuid);
201 assert_eq!(id1, id2);
202 }
203}