1use crate::vault::{base64::Base64Encodable, crypto_box::BoxProvider};
5
6use serde::{Deserialize, Serialize};
7use std::{
8 cmp::Ordering,
9 fmt::{self, Debug, Display, Formatter},
10 hash::Hash,
11 ops::{Add, AddAssign},
12};
13use thiserror::Error as DeriveError;
14
15#[repr(transparent)]
17#[derive(Copy, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)]
18pub struct RecordHint([u8; 24]);
19
20#[repr(transparent)]
22#[derive(Copy, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)]
23pub struct RecordId(pub(crate) ChainId);
24
25#[repr(transparent)]
27#[derive(Copy, Clone, Default, Hash, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)]
28pub struct ClientId(pub Id);
29
30#[repr(transparent)]
32#[derive(Copy, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)]
33pub struct VaultId(pub Id);
34
35#[repr(transparent)]
37#[derive(Copy, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)]
38pub struct ChainId([u8; 24]);
39
40#[repr(transparent)]
42#[derive(Copy, Clone, Hash, Default, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)]
43pub struct Id([u8; 24]);
44
45#[repr(transparent)]
47#[derive(Copy, Clone, Hash, Ord, PartialOrd, Eq, PartialEq, Serialize, Deserialize)]
48pub struct BlobId([u8; 24]);
49
50#[repr(transparent)]
52#[derive(Copy, Clone, Hash, Eq, PartialEq)]
53pub struct Val([u8; 8]);
54
55#[derive(DeriveError, Debug)]
56#[error("invalid length: expected: `{expected}`, found: `{found}`")]
57pub struct InvalidLength {
58 expected: usize,
59 found: usize,
60}
61
62impl RecordHint {
63 pub fn new(hint: impl AsRef<[u8]>) -> Option<Self> {
65 let hint = match hint.as_ref() {
66 hint if hint.len() <= 24 => hint,
67 _ => return None,
68 };
69
70 let mut buf = [0; 24];
72 buf[..hint.len()].copy_from_slice(hint);
73 Some(Self(buf))
74 }
75}
76
77impl Val {
78 pub fn u64(self) -> u64 {
80 u64::from_be_bytes(self.0)
81 }
82}
83
84impl ChainId {
85 pub fn random<P: BoxProvider>() -> Result<Self, P::Error> {
87 let mut buf = [0; 24];
88 P::random_buf(&mut buf)?;
89
90 Ok(Self(buf))
91 }
92
93 pub fn load(data: &[u8]) -> Result<Self, InvalidLength> {
95 data.try_into()
96 }
97}
98
99impl BlobId {
100 pub fn random<P: BoxProvider>() -> Result<Self, P::Error> {
102 let mut buf = [0; 24];
103 P::random_buf(&mut buf)?;
104 Ok(Self(buf))
105 }
106}
107
108impl RecordId {
109 pub fn random<P: BoxProvider>() -> Result<Self, P::Error> {
111 ChainId::random::<P>().map(RecordId)
112 }
113
114 pub fn load(data: &[u8]) -> Result<Self, InvalidLength> {
116 Ok(RecordId(ChainId::load(data)?))
117 }
118}
119
120impl Id {
121 pub fn random<P: BoxProvider>() -> Result<Self, P::Error> {
123 let mut buf = [0; 24];
124 P::random_buf(&mut buf)?;
125
126 Ok(Self(buf))
127 }
128
129 pub fn load(data: &[u8]) -> Result<Self, InvalidLength> {
131 data.try_into()
132 }
133}
134
135impl VaultId {
136 pub fn random<P: BoxProvider>() -> Result<Self, P::Error> {
138 Id::random::<P>().map(VaultId)
139 }
140
141 pub fn load(data: &[u8]) -> Result<Self, InvalidLength> {
143 Ok(VaultId(Id::load(data)?))
144 }
145}
146
147impl ClientId {
148 pub fn random<P: BoxProvider>() -> Result<Self, P::Error> {
150 Id::random::<P>().map(ClientId)
151 }
152
153 pub fn load(data: &[u8]) -> Result<Self, InvalidLength> {
155 Ok(ClientId(Id::load(data)?))
156 }
157}
158
159impl AsRef<[u8]> for RecordHint {
160 fn as_ref(&self) -> &[u8] {
161 &self.0
162 }
163}
164impl Debug for RecordHint {
165 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
166 write!(f, "{}", self.0.base64())
167 }
168}
169
170impl From<[u8; 24]> for RecordHint {
171 fn from(bs: [u8; 24]) -> Self {
172 Self(bs)
173 }
174}
175
176impl From<u64> for Val {
177 fn from(num: u64) -> Self {
178 Self(num.to_be_bytes())
179 }
180}
181
182impl PartialOrd for Val {
183 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
184 self.u64().partial_cmp(&other.u64())
185 }
186}
187
188impl Ord for Val {
189 fn cmp(&self, other: &Self) -> Ordering {
190 self.u64().cmp(&other.u64())
191 }
192}
193
194impl Add<u64> for Val {
195 type Output = Self;
196 fn add(self, rhs: u64) -> Self::Output {
197 Self::from(self.u64() + rhs)
198 }
199}
200
201impl AddAssign<u64> for Val {
202 fn add_assign(&mut self, rhs: u64) {
203 *self = *self + rhs;
204 }
205}
206
207impl Debug for Val {
208 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
209 write!(f, "{}", self.u64())
210 }
211}
212
213impl AsRef<[u8]> for ChainId {
214 fn as_ref(&self) -> &[u8] {
215 &self.0
216 }
217}
218
219impl Debug for ChainId {
220 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
221 write!(f, "Chain({})", self.0.base64())
222 }
223}
224
225impl From<RecordId> for ChainId {
226 fn from(id: RecordId) -> Self {
227 id.0
228 }
229}
230
231impl TryFrom<&[u8]> for ChainId {
232 type Error = InvalidLength;
233
234 fn try_from(bs: &[u8]) -> Result<Self, Self::Error> {
235 if bs.len() != 24 {
236 return Err(InvalidLength {
237 expected: 24,
238 found: bs.len(),
239 });
240 }
241
242 let mut tmp = [0; 24];
243 tmp.copy_from_slice(bs);
244 Ok(Self(tmp))
245 }
246}
247
248impl TryFrom<Vec<u8>> for ChainId {
249 type Error = InvalidLength;
250
251 fn try_from(bs: Vec<u8>) -> Result<Self, Self::Error> {
252 Self::try_from(bs.as_slice())
253 }
254}
255
256impl AsRef<[u8]> for BlobId {
257 fn as_ref(&self) -> &[u8] {
258 &self.0
259 }
260}
261
262impl From<BlobId> for Vec<u8> {
263 fn from(id: BlobId) -> Self {
264 id.0.to_vec()
265 }
266}
267
268impl From<&BlobId> for Vec<u8> {
269 fn from(id: &BlobId) -> Self {
270 id.0.to_vec()
271 }
272}
273
274impl Debug for BlobId {
275 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
276 write!(f, "Blob({})", self.0.base64())
277 }
278}
279
280impl TryFrom<&[u8]> for BlobId {
281 type Error = InvalidLength;
282
283 fn try_from(bs: &[u8]) -> Result<Self, Self::Error> {
284 if bs.len() != 24 {
285 return Err(InvalidLength {
286 expected: 24,
287 found: bs.len(),
288 });
289 }
290
291 let mut tmp = [0; 24];
292 tmp.copy_from_slice(bs);
293 Ok(Self(tmp))
294 }
295}
296
297impl Debug for RecordId {
298 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
299 write!(f, "Record({})", self.0.as_ref().base64())
300 }
301}
302
303impl Display for RecordId {
304 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
305 write!(f, "{}", self.0.as_ref().base64())
306 }
307}
308
309impl From<ChainId> for RecordId {
310 fn from(id: ChainId) -> Self {
311 RecordId(id)
312 }
313}
314
315impl TryFrom<Vec<u8>> for RecordId {
316 type Error = InvalidLength;
317
318 fn try_from(bs: Vec<u8>) -> Result<Self, Self::Error> {
319 Ok(RecordId(bs.try_into()?))
320 }
321}
322
323impl TryFrom<&[u8]> for RecordId {
324 type Error = InvalidLength;
325
326 fn try_from(bs: &[u8]) -> Result<Self, Self::Error> {
327 Ok(RecordId(bs.try_into()?))
328 }
329}
330
331impl AsRef<[u8]> for Id {
332 fn as_ref(&self) -> &[u8] {
333 &self.0
334 }
335}
336
337impl Debug for Id {
338 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
339 write!(f, "Chain({})", self.0.base64())
340 }
341}
342
343impl TryFrom<&[u8]> for Id {
344 type Error = InvalidLength;
345
346 fn try_from(bs: &[u8]) -> Result<Self, Self::Error> {
347 if bs.len() != 24 {
348 return Err(InvalidLength {
349 expected: 24,
350 found: bs.len(),
351 });
352 }
353
354 let mut tmp = [0; 24];
355 tmp.copy_from_slice(bs);
356 Ok(Self(tmp))
357 }
358}
359
360impl TryFrom<Vec<u8>> for Id {
361 type Error = InvalidLength;
362
363 fn try_from(bs: Vec<u8>) -> Result<Self, Self::Error> {
364 Self::try_from(bs.as_slice())
365 }
366}
367
368impl TryFrom<Vec<u8>> for ClientId {
369 type Error = InvalidLength;
370
371 fn try_from(bs: Vec<u8>) -> Result<Self, Self::Error> {
372 Ok(ClientId(bs.try_into()?))
373 }
374}
375
376impl TryFrom<&[u8]> for ClientId {
377 type Error = InvalidLength;
378
379 fn try_from(bs: &[u8]) -> Result<Self, Self::Error> {
380 Ok(ClientId(bs.try_into()?))
381 }
382}
383
384impl Debug for ClientId {
385 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
386 write!(f, "ClientId({})", self.0.as_ref().base64())
387 }
388}
389
390impl TryFrom<Vec<u8>> for VaultId {
391 type Error = InvalidLength;
392
393 fn try_from(bs: Vec<u8>) -> Result<Self, Self::Error> {
394 Ok(VaultId(bs.try_into()?))
395 }
396}
397
398impl TryFrom<&[u8]> for VaultId {
399 type Error = InvalidLength;
400
401 fn try_from(bs: &[u8]) -> Result<Self, Self::Error> {
402 Ok(VaultId(bs.try_into()?))
403 }
404}
405
406impl Debug for VaultId {
407 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
408 write!(f, "VaultId({})", self.0.as_ref().base64())
409 }
410}
411
412impl Into<Vec<u8>> for VaultId {
413 fn into(self) -> Vec<u8> {
414 self.0 .0.to_vec()
415 }
416}
417
418impl AsRef<[u8]> for VaultId {
419 fn as_ref(&self) -> &[u8] {
420 &self.0 .0
421 }
422}
423
424impl Into<Vec<u8>> for ClientId {
425 fn into(self) -> Vec<u8> {
426 self.0 .0.to_vec()
427 }
428}
429
430impl AsRef<[u8]> for ClientId {
431 fn as_ref(&self) -> &[u8] {
432 &self.0 .0
433 }
434}
435
436impl Into<String> for ClientId {
437 fn into(self) -> String {
438 self.0.as_ref().base64()
439 }
440}
441
442impl Into<String> for VaultId {
443 fn into(self) -> String {
444 self.0.as_ref().base64()
445 }
446}