sc_network_types/
multiaddr.rs1use litep2p::types::multiaddr::{
20 Error as LiteP2pError, Iter as LiteP2pIter, Multiaddr as LiteP2pMultiaddr,
21 Protocol as LiteP2pProtocol,
22};
23use multiaddr::Multiaddr as LibP2pMultiaddr;
24use std::{
25 fmt::{self, Debug, Display},
26 net::{IpAddr, Ipv4Addr, Ipv6Addr},
27 str::FromStr,
28};
29
30mod protocol;
31pub use protocol::Protocol;
32
33pub use crate::build_multiaddr as multiaddr;
35
36#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
40pub struct Multiaddr {
41 multiaddr: LiteP2pMultiaddr,
42}
43
44impl Multiaddr {
45 pub fn empty() -> Self {
47 Self { multiaddr: LiteP2pMultiaddr::empty() }
48 }
49
50 pub fn push(&mut self, p: Protocol<'_>) {
52 self.multiaddr.push(p.into())
53 }
54
55 pub fn pop<'a>(&mut self) -> Option<Protocol<'a>> {
57 self.multiaddr.pop().map(Into::into)
58 }
59
60 pub fn with(self, p: Protocol<'_>) -> Self {
62 self.multiaddr.with(p.into()).into()
63 }
64
65 pub fn iter(&self) -> Iter<'_> {
67 self.multiaddr.iter().into()
68 }
69
70 pub fn to_vec(&self) -> Vec<u8> {
72 self.multiaddr.to_vec()
73 }
74}
75
76impl Display for Multiaddr {
77 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78 Display::fmt(&self.multiaddr, f)
79 }
80}
81
82impl Debug for Multiaddr {
84 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85 Debug::fmt(&self.multiaddr, f)
86 }
87}
88
89impl AsRef<[u8]> for Multiaddr {
90 fn as_ref(&self) -> &[u8] {
91 self.multiaddr.as_ref()
92 }
93}
94
95impl From<LiteP2pMultiaddr> for Multiaddr {
96 fn from(multiaddr: LiteP2pMultiaddr) -> Self {
97 Self { multiaddr }
98 }
99}
100
101impl From<Multiaddr> for LiteP2pMultiaddr {
102 fn from(multiaddr: Multiaddr) -> Self {
103 multiaddr.multiaddr
104 }
105}
106
107impl From<LibP2pMultiaddr> for Multiaddr {
108 fn from(multiaddr: LibP2pMultiaddr) -> Self {
109 multiaddr.into_iter().map(Into::into).collect()
110 }
111}
112
113impl From<Multiaddr> for LibP2pMultiaddr {
114 fn from(multiaddr: Multiaddr) -> Self {
115 multiaddr.into_iter().map(Into::into).collect()
116 }
117}
118
119impl From<IpAddr> for Multiaddr {
120 fn from(v: IpAddr) -> Multiaddr {
121 match v {
122 IpAddr::V4(a) => a.into(),
123 IpAddr::V6(a) => a.into(),
124 }
125 }
126}
127
128impl From<Ipv4Addr> for Multiaddr {
129 fn from(v: Ipv4Addr) -> Multiaddr {
130 Protocol::Ip4(v).into()
131 }
132}
133
134impl From<Ipv6Addr> for Multiaddr {
135 fn from(v: Ipv6Addr) -> Multiaddr {
136 Protocol::Ip6(v).into()
137 }
138}
139
140impl TryFrom<Vec<u8>> for Multiaddr {
141 type Error = ParseError;
142
143 fn try_from(v: Vec<u8>) -> Result<Self, ParseError> {
144 let multiaddr = LiteP2pMultiaddr::try_from(v)?;
145 Ok(Self { multiaddr })
146 }
147}
148
149#[derive(Debug, thiserror::Error)]
151pub enum ParseError {
152 #[error("less data than indicated by length")]
154 DataLessThanLen,
155 #[error("invalid multiaddress")]
157 InvalidMultiaddr,
158 #[error("invalid protocol string")]
160 InvalidProtocolString,
161 #[error("unknown protocol '{0}'")]
163 UnknownProtocolString(String),
164 #[error("unknown protocol id {0}")]
166 UnknownProtocolId(u32),
167 #[error("failed to decode unsigned varint: {0}")]
169 InvalidUvar(Box<dyn std::error::Error + Send + Sync>),
170 #[error("multiaddr parsing error: {0}")]
172 ParsingError(Box<dyn std::error::Error + Send + Sync>),
173}
174
175impl From<LiteP2pError> for ParseError {
176 fn from(error: LiteP2pError) -> Self {
177 match error {
178 LiteP2pError::DataLessThanLen => ParseError::DataLessThanLen,
179 LiteP2pError::InvalidMultiaddr => ParseError::InvalidMultiaddr,
180 LiteP2pError::InvalidProtocolString => ParseError::InvalidProtocolString,
181 LiteP2pError::UnknownProtocolString(s) => ParseError::UnknownProtocolString(s),
182 LiteP2pError::UnknownProtocolId(n) => ParseError::UnknownProtocolId(n),
183 LiteP2pError::InvalidUvar(e) => ParseError::InvalidUvar(Box::new(e)),
184 LiteP2pError::ParsingError(e) => ParseError::ParsingError(e),
185 error => ParseError::ParsingError(Box::new(error)),
186 }
187 }
188}
189
190impl FromStr for Multiaddr {
191 type Err = ParseError;
192
193 fn from_str(s: &str) -> Result<Self, Self::Err> {
194 let multiaddr = LiteP2pMultiaddr::from_str(s)?;
195 Ok(Self { multiaddr })
196 }
197}
198
199impl TryFrom<String> for Multiaddr {
200 type Error = ParseError;
201
202 fn try_from(s: String) -> Result<Multiaddr, Self::Error> {
203 Self::from_str(&s)
204 }
205}
206
207impl<'a> TryFrom<&'a str> for Multiaddr {
208 type Error = ParseError;
209
210 fn try_from(s: &'a str) -> Result<Multiaddr, Self::Error> {
211 Self::from_str(s)
212 }
213}
214
215pub struct Iter<'a>(LiteP2pIter<'a>);
217
218impl<'a> Iterator for Iter<'a> {
219 type Item = Protocol<'a>;
220
221 fn next(&mut self) -> Option<Self::Item> {
222 self.0.next().map(Into::into)
223 }
224}
225
226impl<'a> From<LiteP2pIter<'a>> for Iter<'a> {
227 fn from(iter: LiteP2pIter<'a>) -> Self {
228 Self(iter)
229 }
230}
231
232impl<'a> IntoIterator for &'a Multiaddr {
233 type Item = Protocol<'a>;
234 type IntoIter = Iter<'a>;
235
236 fn into_iter(self) -> Iter<'a> {
237 self.multiaddr.into_iter().into()
238 }
239}
240
241impl<'a> FromIterator<Protocol<'a>> for Multiaddr {
242 fn from_iter<T>(iter: T) -> Self
243 where
244 T: IntoIterator<Item = Protocol<'a>>,
245 {
246 LiteP2pMultiaddr::from_iter(iter.into_iter().map(Into::into)).into()
247 }
248}
249
250impl<'a> From<Protocol<'a>> for Multiaddr {
251 fn from(p: Protocol<'a>) -> Multiaddr {
252 let protocol: LiteP2pProtocol = p.into();
253 let multiaddr: LiteP2pMultiaddr = protocol.into();
254 multiaddr.into()
255 }
256}
257
258#[macro_export]
272macro_rules! build_multiaddr {
273 ($($comp:ident $(($param:expr))*),+) => {
274 {
275 use std::iter;
276 let elem = iter::empty::<$crate::multiaddr::Protocol>();
277 $(
278 let elem = {
279 let cmp = $crate::multiaddr::Protocol::$comp $(( $param.into() ))*;
280 elem.chain(iter::once(cmp))
281 };
282 )+
283 elem.collect::<$crate::multiaddr::Multiaddr>()
284 }
285 }
286}