ockam_multiaddr/
proto.rs

1use super::{Buffer, Checked, Code, Protocol};
2use crate::Error;
3use alloc::borrow::Cow;
4use core::fmt;
5use core::ops::Deref;
6use core::str::{self, FromStr};
7use unsigned_varint::encode;
8
9/// An IPv4 address.
10#[cfg(feature = "std")]
11#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
12pub struct Ip4(pub std::net::Ipv4Addr);
13
14#[cfg(feature = "std")]
15impl Ip4 {
16    pub fn new<T: Into<std::net::Ipv4Addr>>(v: T) -> Self {
17        Ip4(v.into())
18    }
19}
20
21#[cfg(feature = "std")]
22impl Deref for Ip4 {
23    type Target = std::net::Ipv4Addr;
24
25    fn deref(&self) -> &Self::Target {
26        &self.0
27    }
28}
29
30#[cfg(feature = "std")]
31impl Protocol<'_> for Ip4 {
32    const CODE: Code = Code::new(4);
33    const PREFIX: &'static str = "ip4";
34
35    fn read_str(input: Checked<&str>) -> Result<Self, Error> {
36        std::net::Ipv4Addr::from_str(&input)
37            .map(Ip4)
38            .map_err(|e| Error::custom(e.into()))
39    }
40
41    fn read_bytes(input: Checked<&[u8]>) -> Result<Self, Error> {
42        let mut b = [0; 4];
43        b.copy_from_slice(&input);
44        Ok(Ip4(std::net::Ipv4Addr::from(b)))
45    }
46
47    fn write_str(&self, f: &mut fmt::Formatter) -> Result<(), Error> {
48        write!(f, "/{}/{}", Self::PREFIX, self.0)?;
49        Ok(())
50    }
51
52    fn write_bytes(&self, buf: &mut dyn Buffer) {
53        let mut b = encode::u32_buffer();
54        let uvi = encode::u32(Self::CODE.into(), &mut b);
55        buf.extend_with(uvi);
56        buf.extend_with(&self.0.octets())
57    }
58}
59
60/// An IPv6 address.
61#[cfg(feature = "std")]
62#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
63pub struct Ip6(pub std::net::Ipv6Addr);
64
65#[cfg(feature = "std")]
66impl Ip6 {
67    pub fn new<T: Into<std::net::Ipv6Addr>>(v: T) -> Self {
68        Ip6(v.into())
69    }
70}
71
72#[cfg(feature = "std")]
73impl Deref for Ip6 {
74    type Target = std::net::Ipv6Addr;
75
76    fn deref(&self) -> &Self::Target {
77        &self.0
78    }
79}
80
81#[cfg(feature = "std")]
82impl Protocol<'_> for Ip6 {
83    const CODE: Code = Code::new(41);
84    const PREFIX: &'static str = "ip6";
85
86    fn read_str(input: Checked<&str>) -> Result<Self, Error> {
87        std::net::Ipv6Addr::from_str(&input)
88            .map(Ip6)
89            .map_err(|e| Error::custom(e.into()))
90    }
91
92    fn read_bytes(input: Checked<&[u8]>) -> Result<Self, Error> {
93        let mut b = [0; 16];
94        b.copy_from_slice(&input);
95        Ok(Ip6(std::net::Ipv6Addr::from(b)))
96    }
97
98    fn write_str(&self, f: &mut fmt::Formatter) -> Result<(), Error> {
99        write!(f, "/{}/{}", Self::PREFIX, self.0)?;
100        Ok(())
101    }
102
103    fn write_bytes(&self, buf: &mut dyn Buffer) {
104        let mut b = encode::u32_buffer();
105        let uvi = encode::u32(Self::CODE.into(), &mut b);
106        buf.extend_with(uvi);
107        buf.extend_with(&self.0.octets())
108    }
109}
110
111/// A TCP port number.
112#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
113pub struct Tcp(pub u16);
114
115impl Tcp {
116    pub fn new(v: u16) -> Self {
117        Tcp(v)
118    }
119}
120
121impl Deref for Tcp {
122    type Target = u16;
123
124    fn deref(&self) -> &Self::Target {
125        &self.0
126    }
127}
128
129impl Protocol<'_> for Tcp {
130    const CODE: Code = Code::new(6);
131    const PREFIX: &'static str = "tcp";
132
133    fn read_str(input: Checked<&str>) -> Result<Self, Error> {
134        u16::from_str(&input).map(Tcp).map_err(Error::message)
135    }
136
137    fn read_bytes(input: Checked<&[u8]>) -> Result<Self, Error> {
138        let mut b = [0; 2];
139        b.copy_from_slice(&input);
140        Ok(Tcp(u16::from_be_bytes(b)))
141    }
142
143    fn write_str(&self, f: &mut fmt::Formatter) -> Result<(), Error> {
144        write!(f, "/{}/{}", Self::PREFIX, self.0)?;
145        Ok(())
146    }
147
148    fn write_bytes(&self, buf: &mut dyn Buffer) {
149        let mut b = encode::u32_buffer();
150        let uvi = encode::u32(Self::CODE.into(), &mut b);
151        buf.extend_with(uvi);
152        buf.extend_with(&self.0.to_be_bytes())
153    }
154}
155
156/// A Udp port number.
157#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
158pub struct Udp(pub u16);
159
160impl Udp {
161    pub fn new(v: u16) -> Self {
162        Udp(v)
163    }
164}
165
166impl Deref for Udp {
167    type Target = u16;
168
169    fn deref(&self) -> &Self::Target {
170        &self.0
171    }
172}
173
174impl Protocol<'_> for Udp {
175    const CODE: Code = Code::new(273);
176    const PREFIX: &'static str = "udp";
177
178    fn read_str(input: Checked<&str>) -> Result<Self, Error> {
179        u16::from_str(&input).map(Udp).map_err(Error::message)
180    }
181
182    fn read_bytes(input: Checked<&[u8]>) -> Result<Self, Error> {
183        let mut b = [0; 2];
184        b.copy_from_slice(&input);
185        Ok(Udp(u16::from_be_bytes(b)))
186    }
187
188    fn write_str(&self, f: &mut fmt::Formatter) -> Result<(), Error> {
189        write!(f, "/{}/{}", Self::PREFIX, self.0)?;
190        Ok(())
191    }
192
193    fn write_bytes(&self, buf: &mut dyn Buffer) {
194        let mut b = encode::u32_buffer();
195        let uvi = encode::u32(Self::CODE.into(), &mut b);
196        buf.extend_with(uvi);
197        buf.extend_with(&self.0.to_be_bytes())
198    }
199}
200
201macro_rules! gen_str_proto {
202    ($t:ident, $c:literal, $p:literal) => {
203        #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
204        pub struct $t<'a>(Cow<'a, str>);
205
206        impl<'a> $t<'a> {
207            pub fn new<S: Into<Cow<'a, str>>>(s: S) -> Self {
208                Self(s.into())
209            }
210        }
211
212        impl Deref for $t<'_> {
213            type Target = str;
214
215            fn deref(&self) -> &Self::Target {
216                &self.0
217            }
218        }
219
220        impl<'a> Protocol<'a> for $t<'a> {
221            const CODE: Code = Code::new($c);
222            const PREFIX: &'static str = $p;
223
224            fn read_str(input: Checked<&'a str>) -> Result<Self, Error> {
225                Ok(Self(Cow::Borrowed(input.0)))
226            }
227
228            fn read_bytes(input: Checked<&'a [u8]>) -> Result<Self, Error> {
229                let s = str::from_utf8(&input).map_err(Error::message)?;
230                Ok(Self(Cow::Borrowed(s)))
231            }
232
233            fn write_str(&self, f: &mut fmt::Formatter) -> Result<(), Error> {
234                write!(f, "/{}/{}", Self::PREFIX, self.0)?;
235                Ok(())
236            }
237
238            fn write_bytes(&self, buf: &mut dyn Buffer) {
239                let mut b = encode::u32_buffer();
240                let uvi = encode::u32(Self::CODE.into(), &mut b);
241                buf.extend_with(uvi);
242                let mut b = encode::usize_buffer();
243                let uvi = encode::usize(self.0.len(), &mut b);
244                buf.extend_with(uvi);
245                buf.extend_with(self.0.as_bytes())
246            }
247        }
248    };
249}
250
251gen_str_proto!(Worker, 102526, "worker");
252gen_str_proto!(DnsAddr, 56, "dnsaddr");
253gen_str_proto!(Service, 62526, "service");
254gen_str_proto!(Node, 72526, "node");
255gen_str_proto!(Project, 82526, "project");
256gen_str_proto!(Space, 92526, "space");
257gen_str_proto!(Secure, 99526, "secure");