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