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