calimero_node_primitives/client/
alias.rs

1use std::str::FromStr;
2
3use calimero_primitives::alias::Alias;
4use calimero_store::key::{self as key, Aliasable, StoreScopeCompat};
5use eyre::{bail, OptionExt};
6
7use super::NodeClient;
8
9impl NodeClient {
10    pub fn create_alias<T>(
11        &self,
12        alias: Alias<T>,
13        scope: Option<T::Scope>,
14        value: T,
15    ) -> eyre::Result<()>
16    where
17        T: Aliasable<Scope: StoreScopeCompat> + AsRef<[u8; 32]>,
18    {
19        let mut handle = self.datastore.handle();
20
21        let key = key::Alias::new(scope, alias).ok_or_eyre("alias requires scope to be present")?;
22
23        if handle.has(&key)? {
24            bail!("alias already exists");
25        }
26
27        let value = (*value.as_ref()).into();
28
29        handle.put(&key, &value)?;
30
31        Ok(())
32    }
33
34    pub fn delete_alias<T>(&self, alias: Alias<T>, scope: Option<T::Scope>) -> eyre::Result<()>
35    where
36        T: Aliasable<Scope: StoreScopeCompat>,
37    {
38        let mut handle = self.datastore.handle();
39
40        let key = key::Alias::new(scope, alias).ok_or_eyre("alias requires scope to be present")?;
41
42        handle.delete(&key)?;
43
44        Ok(())
45    }
46
47    pub fn lookup_alias<T>(
48        &self,
49        alias: Alias<T>,
50        scope: Option<T::Scope>,
51    ) -> eyre::Result<Option<T>>
52    where
53        T: Aliasable<Scope: StoreScopeCompat> + From<[u8; 32]>,
54    {
55        let handle = self.datastore.handle();
56
57        let key = key::Alias::new(scope, alias).ok_or_eyre("alias requires scope to be present")?;
58
59        let Some(value) = handle.get(&key)? else {
60            return Ok(None);
61        };
62
63        Ok(Some((*value).into()))
64    }
65
66    pub fn resolve_alias<T>(
67        &self,
68        alias: Alias<T>,
69        scope: Option<T::Scope>,
70    ) -> eyre::Result<Option<T>>
71    where
72        T: Aliasable<Scope: StoreScopeCompat> + From<[u8; 32]> + FromStr<Err: Into<eyre::Report>>,
73    {
74        if let Some(value) = self.lookup_alias(alias, scope)? {
75            return Ok(Some(value));
76        }
77
78        Ok(alias.as_str().parse().ok())
79    }
80
81    pub fn list_aliases<T>(
82        &self,
83        scope: Option<T::Scope>,
84    ) -> eyre::Result<Vec<(Alias<T>, T, Option<T::Scope>)>>
85    where
86        T: Aliasable + From<[u8; 32]>,
87        T::Scope: Copy + PartialEq + StoreScopeCompat,
88    {
89        let handle = self.datastore.handle();
90
91        let mut iter = handle.iter::<key::Alias>()?;
92
93        let first = scope
94            .map(|scope| {
95                iter.seek(key::Alias::new_unchecked::<T>(Some(scope), [0; 50]))
96                    .transpose()
97                    .map(|k| (k, iter.read()))
98            })
99            .flatten();
100
101        let mut aliases = vec![];
102
103        for (k, v) in first.into_iter().chain(iter.entries()) {
104            let (k, v) = (k?, v?);
105
106            if let Some(expected_scope) = &scope {
107                if let Some(found_scope) = k.scope::<T>() {
108                    if found_scope != *expected_scope {
109                        break;
110                    }
111                }
112            }
113
114            let Some(alias) = k.alias() else {
115                continue;
116            };
117
118            aliases.push((alias, (*v).into(), k.scope::<T>()));
119        }
120
121        Ok(aliases)
122    }
123}