susy_multiaddr/
lib.rs

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