This repository has no description
1.7 kB
54 lines
1use std::sync::Arc;
2
3use knot_types::{AccountDid, OwnerDid, RepoDid, RepoName, RepoRkey};
4use lasso::{Spur, ThreadedRodeo};
5
6#[derive(Debug, Clone, Default)]
7pub(crate) struct Interner(Arc<ThreadedRodeo>);
8
9impl Interner {
10 pub(crate) fn new() -> Self {
11 Self(Arc::new(ThreadedRodeo::new()))
12 }
13}
14
15macro_rules! interned {
16 (@lookup $key:ident of $value:ty { $intern:ident, $get:ident }) => {
17 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
18 pub(crate) struct $key(Spur);
19
20 impl Interner {
21 pub(crate) fn $intern(&self, value: &$value) -> $key {
22 $key(self.0.get_or_intern(value.as_str()))
23 }
24
25 pub(crate) fn $get(&self, value: &$value) -> Option<$key> {
26 self.0.get(value.as_str()).map($key)
27 }
28 }
29 };
30 ($(
31 $key:ident of $value:ty {
32 $intern:ident, $get:ident $(, $resolve:ident, $label:literal)?
33 }
34 )+) => {$(
35 interned!(@lookup $key of $value { $intern, $get });
36
37 $(
38 impl Interner {
39 pub(crate) fn $resolve(&self, key: $key) -> $value {
40 <$value>::new(self.0.resolve(&key.0))
41 .expect(concat!("interned ", $label, " is valid ", $label))
42 }
43 }
44 )?
45 )+};
46}
47
48interned! {
49 AccountKey of AccountDid { intern_account, account, resolve_account, "account DID" }
50 RepoKey of RepoDid { intern_repo, repo, resolve_repo, "repo DID" }
51 OwnerKey of OwnerDid { intern_owner, owner, resolve_owner, "owner DID" }
52 RkeyKey of RepoRkey { intern_rkey, rkey, resolve_rkey, "rkey" }
53 NameKey of RepoName { intern_name, name }
54}