ockam_multiaddr/
registry.rs1use 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}