sc_network_types/
multiaddr.rs1use litep2p::types::multiaddr::{
20 Error as LiteP2pError, Iter as LiteP2pIter, Multiaddr as LiteP2pMultiaddr,
21 Protocol as LiteP2pProtocol,
22};
23use serde_with::{DeserializeFromStr, SerializeDisplay};
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, SerializeDisplay, DeserializeFromStr)]
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}
106impl From<IpAddr> for Multiaddr {
107 fn from(v: IpAddr) -> Multiaddr {
108 match v {
109 IpAddr::V4(a) => a.into(),
110 IpAddr::V6(a) => a.into(),
111 }
112 }
113}
114
115impl From<Ipv4Addr> for Multiaddr {
116 fn from(v: Ipv4Addr) -> Multiaddr {
117 Protocol::Ip4(v).into()
118 }
119}
120
121impl From<Ipv6Addr> for Multiaddr {
122 fn from(v: Ipv6Addr) -> Multiaddr {
123 Protocol::Ip6(v).into()
124 }
125}
126
127impl TryFrom<Vec<u8>> for Multiaddr {
128 type Error = ParseError;
129
130 fn try_from(v: Vec<u8>) -> Result<Self, ParseError> {
131 let multiaddr = LiteP2pMultiaddr::try_from(v)?;
132 Ok(Self { multiaddr })
133 }
134}
135
136#[derive(Debug, thiserror::Error)]
138pub enum ParseError {
139 #[error("less data than indicated by length")]
141 DataLessThanLen,
142 #[error("invalid multiaddress")]
144 InvalidMultiaddr,
145 #[error("invalid protocol string")]
147 InvalidProtocolString,
148 #[error("unknown protocol '{0}'")]
150 UnknownProtocolString(String),
151 #[error("unknown protocol id {0}")]
153 UnknownProtocolId(u32),
154 #[error("failed to decode unsigned varint: {0}")]
156 InvalidUvar(Box<dyn std::error::Error + Send + Sync>),
157 #[error("multiaddr parsing error: {0}")]
159 ParsingError(Box<dyn std::error::Error + Send + Sync>),
160}
161
162impl From<LiteP2pError> for ParseError {
163 fn from(error: LiteP2pError) -> Self {
164 match error {
165 LiteP2pError::DataLessThanLen => ParseError::DataLessThanLen,
166 LiteP2pError::InvalidMultiaddr => ParseError::InvalidMultiaddr,
167 LiteP2pError::InvalidProtocolString => ParseError::InvalidProtocolString,
168 LiteP2pError::UnknownProtocolString(s) => ParseError::UnknownProtocolString(s),
169 LiteP2pError::UnknownProtocolId(n) => ParseError::UnknownProtocolId(n),
170 LiteP2pError::InvalidUvar(e) => ParseError::InvalidUvar(Box::new(e)),
171 LiteP2pError::ParsingError(e) => ParseError::ParsingError(e),
172 error => ParseError::ParsingError(Box::new(error)),
173 }
174 }
175}
176
177impl FromStr for Multiaddr {
178 type Err = ParseError;
179
180 fn from_str(s: &str) -> Result<Self, Self::Err> {
181 let multiaddr = LiteP2pMultiaddr::from_str(s)?;
182 Ok(Self { multiaddr })
183 }
184}
185
186impl TryFrom<String> for Multiaddr {
187 type Error = ParseError;
188
189 fn try_from(s: String) -> Result<Multiaddr, Self::Error> {
190 Self::from_str(&s)
191 }
192}
193
194impl<'a> TryFrom<&'a str> for Multiaddr {
195 type Error = ParseError;
196
197 fn try_from(s: &'a str) -> Result<Multiaddr, Self::Error> {
198 Self::from_str(s)
199 }
200}
201
202pub struct Iter<'a>(LiteP2pIter<'a>);
204
205impl<'a> Iterator for Iter<'a> {
206 type Item = Protocol<'a>;
207
208 fn next(&mut self) -> Option<Self::Item> {
209 self.0.next().map(Into::into)
210 }
211}
212
213impl<'a> From<LiteP2pIter<'a>> for Iter<'a> {
214 fn from(iter: LiteP2pIter<'a>) -> Self {
215 Self(iter)
216 }
217}
218
219impl<'a> IntoIterator for &'a Multiaddr {
220 type Item = Protocol<'a>;
221 type IntoIter = Iter<'a>;
222
223 fn into_iter(self) -> Iter<'a> {
224 self.multiaddr.into_iter().into()
225 }
226}
227
228impl<'a> FromIterator<Protocol<'a>> for Multiaddr {
229 fn from_iter<T>(iter: T) -> Self
230 where
231 T: IntoIterator<Item = Protocol<'a>>,
232 {
233 LiteP2pMultiaddr::from_iter(iter.into_iter().map(Into::into)).into()
234 }
235}
236
237impl<'a> From<Protocol<'a>> for Multiaddr {
238 fn from(p: Protocol<'a>) -> Multiaddr {
239 let protocol: LiteP2pProtocol = p.into();
240 let multiaddr: LiteP2pMultiaddr = protocol.into();
241 multiaddr.into()
242 }
243}
244
245#[macro_export]
259macro_rules! build_multiaddr {
260 ($($comp:ident $(($param:expr))*),+) => {
261 {
262 use std::iter;
263 let elem = iter::empty::<$crate::multiaddr::Protocol>();
264 $(
265 let elem = {
266 let cmp = $crate::multiaddr::Protocol::$comp $(( $param.into() ))*;
267 elem.chain(iter::once(cmp))
268 };
269 )+
270 elem.collect::<$crate::multiaddr::Multiaddr>()
271 }
272 }
273}