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#[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#[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#[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#[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");