ockam_multiaddr/
registry.rs

1use super::{Code, Codec, Protocol};
2use crate::codec::StdCodec;
3use crate::proto::{DnsAddr, Node, Project, Secure, Service, Space, Tcp, Udp, Worker};
4use alloc::collections::btree_map::BTreeMap;
5use alloc::sync::Arc;
6use core::fmt;
7
8#[derive(Clone)]
9pub struct Registry {
10    inner: Arc<RegistryImpl>,
11}
12
13struct RegistryImpl {
14    bytes: BTreeMap<Code, Arc<dyn Codec>>,
15    strings: BTreeMap<&'static str, Arc<dyn Codec>>,
16}
17
18impl fmt::Debug for Registry {
19    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20        f.write_str("Registry")
21    }
22}
23
24impl Default for Registry {
25    fn default() -> Self {
26        let std_codec = Arc::new(StdCodec);
27        let mut r = RegistryBuilder::new();
28        r.register(Worker::CODE, Worker::PREFIX, std_codec.clone());
29        r.register(Tcp::CODE, Tcp::PREFIX, std_codec.clone());
30        r.register(Udp::CODE, Udp::PREFIX, std_codec.clone());
31        r.register(DnsAddr::CODE, DnsAddr::PREFIX, std_codec.clone());
32        #[allow(clippy::redundant_clone)]
33        r.register(Service::CODE, Service::PREFIX, std_codec.clone());
34        #[allow(clippy::redundant_clone)]
35        r.register(Node::CODE, Node::PREFIX, std_codec.clone());
36        #[allow(clippy::redundant_clone)]
37        r.register(Project::CODE, Project::PREFIX, std_codec.clone());
38        #[allow(clippy::redundant_clone)]
39        r.register(Space::CODE, Space::PREFIX, std_codec.clone());
40        #[allow(clippy::redundant_clone)]
41        r.register(Secure::CODE, Secure::PREFIX, std_codec.clone());
42        #[cfg(feature = "std")]
43        r.register(
44            crate::proto::Ip4::CODE,
45            crate::proto::Ip4::PREFIX,
46            std_codec.clone(),
47        )
48        .register(
49            crate::proto::Ip6::CODE,
50            crate::proto::Ip6::PREFIX,
51            std_codec,
52        );
53        r.finish()
54    }
55}
56
57impl Registry {
58    pub fn get_by_code(&self, code: Code) -> Option<Arc<dyn Codec>> {
59        self.inner.bytes.get(&code).cloned()
60    }
61
62    pub fn get_by_prefix(&self, prefix: &str) -> Option<Arc<dyn Codec>> {
63        self.inner.strings.get(prefix).cloned()
64    }
65
66    pub fn codes(&self) -> impl Iterator<Item = Code> + '_ {
67        self.inner.bytes.keys().copied()
68    }
69
70    pub fn prefixes(&self) -> impl Iterator<Item = &str> + '_ {
71        self.inner.strings.keys().copied()
72    }
73}
74
75pub struct RegistryBuilder(RegistryImpl);
76
77impl Default for RegistryBuilder {
78    fn default() -> Self {
79        RegistryBuilder::new()
80    }
81}
82
83impl RegistryBuilder {
84    pub fn new() -> Self {
85        RegistryBuilder(RegistryImpl {
86            bytes: BTreeMap::new(),
87            strings: BTreeMap::new(),
88        })
89    }
90
91    pub fn has_code(&self, c: Code) -> bool {
92        self.0.bytes.contains_key(&c)
93    }
94
95    pub fn has_prefix(&self, prefix: &str) -> bool {
96        self.0.strings.contains_key(prefix)
97    }
98
99    pub fn register<T>(&mut self, code: Code, prefix: &'static str, codec: Arc<T>) -> &mut Self
100    where
101        T: Codec + 'static,
102    {
103        self.0.bytes.insert(code, codec.clone());
104        self.0.strings.insert(prefix, codec);
105        self
106    }
107
108    pub fn finish(self) -> Registry {
109        Registry {
110            inner: Arc::new(self.0),
111        }
112    }
113}