parity_multiaddr/
lib.rs

1///! Implementation of [multiaddr](https://github.com/jbenet/multiaddr) in Rust.
2
3pub use multihash;
4
5mod protocol;
6mod onion_addr;
7mod errors;
8
9#[cfg(feature = "url")]
10mod from_url;
11
12use serde::{
13    Deserialize,
14    Deserializer,
15    Serialize,
16    Serializer,
17    de::{self, Error as DeserializerError}
18};
19use std::{
20    convert::TryFrom,
21    fmt,
22    io,
23    iter::FromIterator,
24    net::{IpAddr, Ipv4Addr, Ipv6Addr},
25    result::Result as StdResult,
26    str::FromStr,
27    sync::Arc
28};
29pub use self::errors::{Result, Error};
30pub use self::protocol::Protocol;
31pub use self::onion_addr::Onion3Addr;
32
33#[cfg(feature = "url")]
34pub use self::from_url::{FromUrlErr, from_url, from_url_lossy};
35
36static_assertions::const_assert! {
37    // This check is most certainly overkill right now, but done here
38    // anyway to ensure the `as u64` casts in this crate are safe.
39    std::mem::size_of::<usize>() <= std::mem::size_of::<u64>()
40}
41
42/// Representation of a Multiaddr.
43#[allow(clippy::rc_buffer)]
44#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
45pub struct Multiaddr { bytes: Arc<Vec<u8>> }
46
47impl Multiaddr {
48    /// Create a new, empty multiaddress.
49    pub fn empty() -> Self {
50        Self { bytes: Arc::new(Vec::new()) }
51    }
52
53    /// Create a new, empty multiaddress with the given capacity.
54    pub fn with_capacity(n: usize) -> Self {
55        Self { bytes: Arc::new(Vec::with_capacity(n)) }
56    }
57
58    /// Return the length in bytes of this multiaddress.
59    pub fn len(&self) -> usize {
60        self.bytes.len()
61    }
62
63    /// Returns true if the length of this multiaddress is 0.
64    pub fn is_empty(&self) -> bool {
65        self.bytes.len() == 0
66    }
67
68    /// Return a copy of this [`Multiaddr`]'s byte representation.
69    pub fn to_vec(&self) -> Vec<u8> {
70        Vec::from(&self.bytes[..])
71    }
72
73    /// Adds an already-parsed address component to the end of this multiaddr.
74    ///
75    /// # Examples
76    ///
77    /// ```
78    /// use parity_multiaddr::{Multiaddr, Protocol};
79    ///
80    /// let mut address: Multiaddr = "/ip4/127.0.0.1".parse().unwrap();
81    /// address.push(Protocol::Tcp(10000));
82    /// assert_eq!(address, "/ip4/127.0.0.1/tcp/10000".parse().unwrap());
83    /// ```
84    ///
85    pub fn push(&mut self, p: Protocol<'_>) {
86        let mut w = io::Cursor::<&mut Vec<u8>>::new(Arc::make_mut(&mut self.bytes));
87        w.set_position(w.get_ref().len() as u64);
88        p.write_bytes(&mut w).expect("Writing to a `io::Cursor<&mut Vec<u8>>` never fails.")
89    }
90
91    /// Pops the last `Protocol` of this multiaddr, or `None` if the multiaddr is empty.
92    /// ```
93    /// use parity_multiaddr::{Multiaddr, Protocol};
94    ///
95    /// let mut address: Multiaddr = "/ip4/127.0.0.1/udt/sctp/5678".parse().unwrap();
96    ///
97    /// assert_eq!(address.pop().unwrap(), Protocol::Sctp(5678));
98    /// assert_eq!(address.pop().unwrap(), Protocol::Udt);
99    /// ```
100    ///
101    pub fn pop<'a>(&mut self) -> Option<Protocol<'a>> {
102        let mut slice = &self.bytes[..]; // the remaining multiaddr slice
103        if slice.is_empty() {
104            return None
105        }
106        let protocol = loop {
107            let (p, s) = Protocol::from_bytes(slice).expect("`slice` is a valid `Protocol`.");
108            if s.is_empty() {
109                break p.acquire()
110            }
111            slice = s
112        };
113        let remaining_len = self.bytes.len() - slice.len();
114        Arc::make_mut(&mut self.bytes).truncate(remaining_len);
115        Some(protocol)
116    }
117
118    /// Like [`Multiaddr::push`] but consumes `self`.
119    pub fn with(mut self, p: Protocol<'_>) -> Self {
120        let mut w = io::Cursor::<&mut Vec<u8>>::new(Arc::make_mut(&mut self.bytes));
121        w.set_position(w.get_ref().len() as u64);
122        p.write_bytes(&mut w).expect("Writing to a `io::Cursor<&mut Vec<u8>>` never fails.");
123        self
124    }
125
126    /// Returns the components of this multiaddress.
127    ///
128    /// # Example
129    ///
130    /// ```rust
131    /// use std::net::Ipv4Addr;
132    /// use parity_multiaddr::{Multiaddr, Protocol};
133    ///
134    /// let address: Multiaddr = "/ip4/127.0.0.1/udt/sctp/5678".parse().unwrap();
135    ///
136    /// let components = address.iter().collect::<Vec<_>>();
137    /// assert_eq!(components[0], Protocol::Ip4(Ipv4Addr::new(127, 0, 0, 1)));
138    /// assert_eq!(components[1], Protocol::Udt);
139    /// assert_eq!(components[2], Protocol::Sctp(5678));
140    /// ```
141    ///
142    pub fn iter(&self) -> Iter<'_> {
143        Iter(&self.bytes)
144    }
145
146    /// Replace a [`Protocol`] at some position in this `Multiaddr`.
147    ///
148    /// The parameter `at` denotes the index of the protocol at which the function
149    /// `by` will be applied to the current protocol, returning an optional replacement.
150    ///
151    /// If `at` is out of bounds or `by` does not yield a replacement value,
152    /// `None` will be returned. Otherwise a copy of this `Multiaddr` with the
153    /// updated `Protocol` at position `at` will be returned.
154    pub fn replace<'a, F>(&self, at: usize, by: F) -> Option<Multiaddr>
155    where
156        F: FnOnce(&Protocol<'_>) -> Option<Protocol<'a>>
157    {
158        let mut address = Multiaddr::with_capacity(self.len());
159        let mut fun = Some(by);
160        let mut replaced = false;
161
162        for (i, p) in self.iter().enumerate() {
163            if i == at {
164                let f = fun.take().expect("i == at only happens once");
165                if let Some(q) = f(&p) {
166                    address = address.with(q);
167                    replaced = true;
168                    continue
169                }
170                return None
171            }
172            address = address.with(p)
173        }
174
175        if replaced { Some(address) } else { None }
176    }
177
178    /// Checks whether the given `Multiaddr` is a suffix of this `Multiaddr`.
179    pub fn ends_with(&self, other: &Multiaddr) -> bool {
180        let n = self.bytes.len();
181        let m = other.bytes.len();
182        if n < m {
183            return false
184        }
185        self.bytes[(n - m) ..] == other.bytes[..]
186    }
187}
188
189impl fmt::Debug for Multiaddr {
190    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
191        self.to_string().fmt(f)
192    }
193}
194
195impl fmt::Display for Multiaddr {
196    /// Convert a Multiaddr to a string
197    ///
198    /// # Example
199    ///
200    /// ```
201    /// use parity_multiaddr::Multiaddr;
202    ///
203    /// let address: Multiaddr = "/ip4/127.0.0.1/udt".parse().unwrap();
204    /// assert_eq!(address.to_string(), "/ip4/127.0.0.1/udt");
205    /// ```
206    ///
207    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
208        for s in self.iter() {
209            s.to_string().fmt(f)?;
210        }
211        Ok(())
212    }
213}
214
215impl AsRef<[u8]> for Multiaddr {
216    fn as_ref(&self) -> &[u8] {
217        self.bytes.as_ref()
218    }
219}
220
221impl<'a> IntoIterator for &'a Multiaddr {
222    type Item = Protocol<'a>;
223    type IntoIter = Iter<'a>;
224
225    fn into_iter(self) -> Iter<'a> {
226        Iter(&self.bytes)
227    }
228}
229
230impl<'a> FromIterator<Protocol<'a>> for Multiaddr {
231    fn from_iter<T>(iter: T) -> Self
232    where
233        T: IntoIterator<Item = Protocol<'a>>,
234    {
235        let mut writer = Vec::new();
236        for cmp in iter {
237            cmp.write_bytes(&mut writer).expect("Writing to a `Vec` never fails.");
238        }
239        Multiaddr { bytes: Arc::new(writer) }
240    }
241}
242
243impl FromStr for Multiaddr {
244    type Err = Error;
245
246    fn from_str(input: &str) -> Result<Self> {
247        let mut writer = Vec::new();
248        let mut parts = input.split('/').peekable();
249
250        if Some("") != parts.next() {
251            // A multiaddr must start with `/`
252            return Err(Error::InvalidMultiaddr)
253        }
254
255        while parts.peek().is_some() {
256            let p = Protocol::from_str_parts(&mut parts)?;
257            p.write_bytes(&mut writer).expect("Writing to a `Vec` never fails.");
258        }
259
260        Ok(Multiaddr { bytes: Arc::new(writer) })
261    }
262}
263
264/// Iterator over `Multiaddr` [`Protocol`]s.
265pub struct Iter<'a>(&'a [u8]);
266
267impl<'a> Iterator for Iter<'a> {
268    type Item = Protocol<'a>;
269
270    fn next(&mut self) -> Option<Self::Item> {
271        if self.0.is_empty() {
272            return None;
273        }
274
275        let (p, next_data) =
276            Protocol::from_bytes(self.0).expect("`Multiaddr` is known to be valid.");
277
278        self.0 = next_data;
279        Some(p)
280    }
281}
282
283impl<'a> From<Protocol<'a>> for Multiaddr {
284    fn from(p: Protocol<'a>) -> Multiaddr {
285        let mut w = Vec::new();
286        p.write_bytes(&mut w).expect("Writing to a `Vec` never fails.");
287        Multiaddr { bytes: Arc::new(w) }
288    }
289}
290
291impl From<IpAddr> for Multiaddr {
292    fn from(v: IpAddr) -> Multiaddr {
293        match v {
294            IpAddr::V4(a) => a.into(),
295            IpAddr::V6(a) => a.into()
296        }
297    }
298}
299
300impl From<Ipv4Addr> for Multiaddr {
301    fn from(v: Ipv4Addr) -> Multiaddr {
302        Protocol::Ip4(v).into()
303    }
304}
305
306impl From<Ipv6Addr> for Multiaddr {
307    fn from(v: Ipv6Addr) -> Multiaddr {
308        Protocol::Ip6(v).into()
309    }
310}
311
312impl TryFrom<Vec<u8>> for Multiaddr {
313    type Error = Error;
314
315    fn try_from(v: Vec<u8>) -> Result<Self> {
316        // Check if the argument is a valid `Multiaddr` by reading its protocols.
317        let mut slice = &v[..];
318        while !slice.is_empty() {
319            let (_, s) = Protocol::from_bytes(slice)?;
320            slice = s
321        }
322        Ok(Multiaddr { bytes: Arc::new(v) })
323    }
324}
325
326impl TryFrom<String> for Multiaddr {
327    type Error = Error;
328
329    fn try_from(s: String) -> Result<Multiaddr> {
330        s.parse()
331    }
332}
333
334impl<'a> TryFrom<&'a str> for Multiaddr {
335    type Error = Error;
336
337    fn try_from(s: &'a str) -> Result<Multiaddr> {
338        s.parse()
339    }
340}
341
342impl Serialize for Multiaddr {
343    fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
344    where
345        S: Serializer,
346    {
347        if serializer.is_human_readable() {
348            serializer.serialize_str(&self.to_string())
349        } else {
350            serializer.serialize_bytes(self.as_ref())
351        }
352    }
353}
354
355impl<'de> Deserialize<'de> for Multiaddr {
356    fn deserialize<D>(deserializer: D) -> StdResult<Self, D::Error>
357    where
358        D: Deserializer<'de>,
359    {
360        struct Visitor { is_human_readable: bool };
361
362        impl<'de> de::Visitor<'de> for Visitor {
363            type Value = Multiaddr;
364
365            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
366                formatter.write_str("multiaddress")
367            }
368            fn visit_seq<A: de::SeqAccess<'de>>(self, mut seq: A) -> StdResult<Self::Value, A::Error> {
369                let mut buf: Vec<u8> = Vec::with_capacity(std::cmp::min(seq.size_hint().unwrap_or(0), 4096));
370                while let Some(e) = seq.next_element()? { buf.push(e); }
371                if self.is_human_readable {
372                    let s = String::from_utf8(buf).map_err(DeserializerError::custom)?;
373                    s.parse().map_err(DeserializerError::custom)
374                } else {
375                    Multiaddr::try_from(buf).map_err(DeserializerError::custom)
376                }
377            }
378            fn visit_str<E: de::Error>(self, v: &str) -> StdResult<Self::Value, E> {
379                v.parse().map_err(DeserializerError::custom)
380            }
381            fn visit_borrowed_str<E: de::Error>(self, v: &'de str) -> StdResult<Self::Value, E> {
382                self.visit_str(v)
383            }
384            fn visit_string<E: de::Error>(self, v: String) -> StdResult<Self::Value, E> {
385                self.visit_str(&v)
386            }
387            fn visit_bytes<E: de::Error>(self, v: &[u8]) -> StdResult<Self::Value, E> {
388                self.visit_byte_buf(v.into())
389            }
390            fn visit_borrowed_bytes<E: de::Error>(self, v: &'de [u8]) -> StdResult<Self::Value, E> {
391                self.visit_byte_buf(v.into())
392            }
393            fn visit_byte_buf<E: de::Error>(self, v: Vec<u8>) -> StdResult<Self::Value, E> {
394                Multiaddr::try_from(v).map_err(DeserializerError::custom)
395            }
396        }
397
398        if deserializer.is_human_readable() {
399            deserializer.deserialize_str(Visitor { is_human_readable: true })
400        } else {
401            deserializer.deserialize_bytes(Visitor { is_human_readable: false })
402        }
403    }
404}
405
406/// Easy way for a user to create a `Multiaddr`.
407///
408/// Example:
409///
410/// ```rust
411/// # use parity_multiaddr::multiaddr;
412/// let addr = multiaddr!(Ip4([127, 0, 0, 1]), Tcp(10500u16));
413/// ```
414///
415/// Each element passed to `multiaddr!` should be a variant of the `Protocol` enum. The
416/// optional parameter is turned into the proper type with the `Into` trait.
417///
418/// For example, `Ip4([127, 0, 0, 1])` works because `Ipv4Addr` implements `From<[u8; 4]>`.
419#[macro_export]
420macro_rules! multiaddr {
421    ($($comp:ident $(($param:expr))*),+) => {
422        {
423            use std::iter;
424            let elem = iter::empty::<$crate::Protocol>();
425            $(
426                let elem = {
427                    let cmp = $crate::Protocol::$comp $(( $param.into() ))*;
428                    elem.chain(iter::once(cmp))
429                };
430            )+
431            elem.collect::<$crate::Multiaddr>()
432        }
433    }
434}