1use std::fmt;
7
8use serde::{Deserialize, Serialize};
9
10#[derive(
12 Debug,
13 Clone,
14 Copy,
15 PartialEq,
16 Eq,
17 Hash,
18 Serialize,
19 Deserialize,
20 zerompk::ToMessagePack,
21 zerompk::FromMessagePack,
22 rkyv::Archive,
23 rkyv::Serialize,
24 rkyv::Deserialize,
25)]
26pub struct TenantId(u32);
27
28impl TenantId {
29 pub const fn new(id: u32) -> Self {
30 Self(id)
31 }
32
33 pub const fn as_u32(self) -> u32 {
34 self.0
35 }
36}
37
38impl fmt::Display for TenantId {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 write!(f, "tenant:{}", self.0)
41 }
42}
43
44#[derive(
46 Debug,
47 Clone,
48 PartialEq,
49 Eq,
50 Hash,
51 Serialize,
52 Deserialize,
53 rkyv::Archive,
54 rkyv::Serialize,
55 rkyv::Deserialize,
56)]
57pub struct CollectionId(String);
58
59impl CollectionId {
60 pub fn new(id: impl Into<String>) -> Self {
61 Self(id.into())
62 }
63
64 pub fn as_str(&self) -> &str {
65 &self.0
66 }
67}
68
69impl fmt::Display for CollectionId {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 f.write_str(&self.0)
72 }
73}
74
75#[derive(
77 Debug,
78 Clone,
79 PartialEq,
80 Eq,
81 Hash,
82 Serialize,
83 Deserialize,
84 rkyv::Archive,
85 rkyv::Serialize,
86 rkyv::Deserialize,
87)]
88pub struct DocumentId(String);
89
90impl DocumentId {
91 pub fn new(id: impl Into<String>) -> Self {
92 Self(id.into())
93 }
94
95 pub fn as_str(&self) -> &str {
96 &self.0
97 }
98}
99
100impl fmt::Display for DocumentId {
101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102 f.write_str(&self.0)
103 }
104}
105
106#[derive(
109 Debug,
110 Clone,
111 PartialEq,
112 Eq,
113 Hash,
114 Serialize,
115 Deserialize,
116 rkyv::Archive,
117 rkyv::Serialize,
118 rkyv::Deserialize,
119 zerompk::ToMessagePack,
120 zerompk::FromMessagePack,
121)]
122pub struct NodeId(String);
123
124impl NodeId {
125 pub fn new(id: impl Into<String>) -> Self {
126 Self(id.into())
127 }
128
129 pub fn as_str(&self) -> &str {
130 &self.0
131 }
132}
133
134impl fmt::Display for NodeId {
135 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136 f.write_str(&self.0)
137 }
138}
139
140#[derive(
142 Debug,
143 Clone,
144 PartialEq,
145 Eq,
146 Hash,
147 Serialize,
148 Deserialize,
149 rkyv::Archive,
150 rkyv::Serialize,
151 rkyv::Deserialize,
152)]
153pub struct EdgeId(String);
154
155impl EdgeId {
156 pub fn new(id: impl Into<String>) -> Self {
157 Self(id.into())
158 }
159
160 pub fn as_str(&self) -> &str {
161 &self.0
162 }
163
164 pub fn from_components(src: &str, dst: &str, label: &str) -> Self {
166 Self(format!("{src}--{label}-->{dst}"))
167 }
168}
169
170impl fmt::Display for EdgeId {
171 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
172 f.write_str(&self.0)
173 }
174}
175
176#[derive(
178 Debug,
179 Clone,
180 PartialEq,
181 Eq,
182 Hash,
183 Serialize,
184 Deserialize,
185 rkyv::Archive,
186 rkyv::Serialize,
187 rkyv::Deserialize,
188)]
189pub struct ShapeId(String);
190
191impl ShapeId {
192 pub fn new(id: impl Into<String>) -> Self {
193 Self(id.into())
194 }
195
196 pub fn as_str(&self) -> &str {
197 &self.0
198 }
199}
200
201impl fmt::Display for ShapeId {
202 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
203 f.write_str(&self.0)
204 }
205}
206
207impl From<String> for ShapeId {
208 fn from(s: String) -> Self {
209 Self(s)
210 }
211}
212
213impl From<&str> for ShapeId {
214 fn from(s: &str) -> Self {
215 Self(s.to_owned())
216 }
217}
218
219#[cfg(test)]
220mod tests {
221 use super::*;
222
223 #[test]
224 fn tenant_id_display() {
225 let t = TenantId::new(42);
226 assert_eq!(t.to_string(), "tenant:42");
227 assert_eq!(t.as_u32(), 42);
228 }
229
230 #[test]
231 fn collection_id() {
232 let c = CollectionId::new("embeddings");
233 assert_eq!(c.as_str(), "embeddings");
234 assert_eq!(c.to_string(), "embeddings");
235 }
236
237 #[test]
238 fn document_id_str() {
239 let d = DocumentId::new("doc-abc-123");
240 assert_eq!(d.as_str(), "doc-abc-123");
241 }
242
243 #[test]
244 fn node_id() {
245 let n = NodeId::new("concept:rust");
246 assert_eq!(n.as_str(), "concept:rust");
247 }
248
249 #[test]
250 fn edge_id_from_components() {
251 let e = EdgeId::from_components("alice", "bob", "KNOWS");
252 assert_eq!(e.as_str(), "alice--KNOWS-->bob");
253 }
254
255 #[test]
256 fn shape_id_from_str() {
257 let s = ShapeId::from("shape-001");
258 assert_eq!(s.as_str(), "shape-001");
259 }
260
261 #[test]
262 fn serde_roundtrip() {
263 let tid = TenantId::new(7);
264 let json = sonic_rs::to_string(&tid).unwrap();
265 let decoded: TenantId = sonic_rs::from_str(&json).unwrap();
266 assert_eq!(tid, decoded);
267 }
268}