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)]
120pub struct NodeId(String);
121
122impl NodeId {
123 pub fn new(id: impl Into<String>) -> Self {
124 Self(id.into())
125 }
126
127 pub fn as_str(&self) -> &str {
128 &self.0
129 }
130}
131
132impl fmt::Display for NodeId {
133 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
134 f.write_str(&self.0)
135 }
136}
137
138#[derive(
140 Debug,
141 Clone,
142 PartialEq,
143 Eq,
144 Hash,
145 Serialize,
146 Deserialize,
147 rkyv::Archive,
148 rkyv::Serialize,
149 rkyv::Deserialize,
150)]
151pub struct EdgeId(String);
152
153impl EdgeId {
154 pub fn new(id: impl Into<String>) -> Self {
155 Self(id.into())
156 }
157
158 pub fn as_str(&self) -> &str {
159 &self.0
160 }
161
162 pub fn from_components(src: &str, dst: &str, label: &str) -> Self {
164 Self(format!("{src}--{label}-->{dst}"))
165 }
166}
167
168impl fmt::Display for EdgeId {
169 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
170 f.write_str(&self.0)
171 }
172}
173
174#[derive(
176 Debug,
177 Clone,
178 PartialEq,
179 Eq,
180 Hash,
181 Serialize,
182 Deserialize,
183 rkyv::Archive,
184 rkyv::Serialize,
185 rkyv::Deserialize,
186)]
187pub struct ShapeId(String);
188
189impl ShapeId {
190 pub fn new(id: impl Into<String>) -> Self {
191 Self(id.into())
192 }
193
194 pub fn as_str(&self) -> &str {
195 &self.0
196 }
197}
198
199impl fmt::Display for ShapeId {
200 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
201 f.write_str(&self.0)
202 }
203}
204
205impl From<String> for ShapeId {
206 fn from(s: String) -> Self {
207 Self(s)
208 }
209}
210
211impl From<&str> for ShapeId {
212 fn from(s: &str) -> Self {
213 Self(s.to_owned())
214 }
215}
216
217#[cfg(test)]
218mod tests {
219 use super::*;
220
221 #[test]
222 fn tenant_id_display() {
223 let t = TenantId::new(42);
224 assert_eq!(t.to_string(), "tenant:42");
225 assert_eq!(t.as_u32(), 42);
226 }
227
228 #[test]
229 fn collection_id() {
230 let c = CollectionId::new("embeddings");
231 assert_eq!(c.as_str(), "embeddings");
232 assert_eq!(c.to_string(), "embeddings");
233 }
234
235 #[test]
236 fn document_id_str() {
237 let d = DocumentId::new("doc-abc-123");
238 assert_eq!(d.as_str(), "doc-abc-123");
239 }
240
241 #[test]
242 fn node_id() {
243 let n = NodeId::new("concept:rust");
244 assert_eq!(n.as_str(), "concept:rust");
245 }
246
247 #[test]
248 fn edge_id_from_components() {
249 let e = EdgeId::from_components("alice", "bob", "KNOWS");
250 assert_eq!(e.as_str(), "alice--KNOWS-->bob");
251 }
252
253 #[test]
254 fn shape_id_from_str() {
255 let s = ShapeId::from("shape-001");
256 assert_eq!(s.as_str(), "shape-001");
257 }
258
259 #[test]
260 fn serde_roundtrip() {
261 let tid = TenantId::new(7);
262 let json = sonic_rs::to_string(&tid).unwrap();
263 let decoded: TenantId = sonic_rs::from_str(&json).unwrap();
264 assert_eq!(tid, decoded);
265 }
266}