1pub 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    std::mem::size_of::<usize>() <= std::mem::size_of::<u64>()
40}
41
42#[allow(clippy::rc_buffer)]
44#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
45pub struct Multiaddr { bytes: Arc<Vec<u8>> }
46
47impl Multiaddr {
48    pub fn empty() -> Self {
50        Self { bytes: Arc::new(Vec::new()) }
51    }
52
53    pub fn with_capacity(n: usize) -> Self {
55        Self { bytes: Arc::new(Vec::with_capacity(n)) }
56    }
57
58    pub fn len(&self) -> usize {
60        self.bytes.len()
61    }
62
63    pub fn is_empty(&self) -> bool {
65        self.bytes.len() == 0
66    }
67
68    pub fn to_vec(&self) -> Vec<u8> {
70        Vec::from(&self.bytes[..])
71    }
72
73    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    pub fn pop<'a>(&mut self) -> Option<Protocol<'a>> {
102        let mut slice = &self.bytes[..]; 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    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    pub fn iter(&self) -> Iter<'_> {
143        Iter(&self.bytes)
144    }
145
146    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
179impl fmt::Debug for Multiaddr {
180    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
181        self.to_string().fmt(f)
182    }
183}
184
185impl fmt::Display for Multiaddr {
186    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
198        for s in self.iter() {
199            s.to_string().fmt(f)?;
200        }
201        Ok(())
202    }
203}
204
205impl AsRef<[u8]> for Multiaddr {
206    fn as_ref(&self) -> &[u8] {
207        self.bytes.as_ref()
208    }
209}
210
211impl<'a> IntoIterator for &'a Multiaddr {
212    type Item = Protocol<'a>;
213    type IntoIter = Iter<'a>;
214
215    fn into_iter(self) -> Iter<'a> {
216        Iter(&self.bytes)
217    }
218}
219
220impl<'a> FromIterator<Protocol<'a>> for Multiaddr {
221    fn from_iter<T>(iter: T) -> Self
222    where
223        T: IntoIterator<Item = Protocol<'a>>,
224    {
225        let mut writer = Vec::new();
226        for cmp in iter {
227            cmp.write_bytes(&mut writer).expect("Writing to a `Vec` never fails.");
228        }
229        Multiaddr { bytes: Arc::new(writer) }
230    }
231}
232
233impl FromStr for Multiaddr {
234    type Err = Error;
235
236    fn from_str(input: &str) -> Result<Self> {
237        let mut writer = Vec::new();
238        let mut parts = input.split('/').peekable();
239
240        if Some("") != parts.next() {
241            return Err(Error::InvalidMultiaddr)
243        }
244
245        while parts.peek().is_some() {
246            let p = Protocol::from_str_parts(&mut parts)?;
247            p.write_bytes(&mut writer).expect("Writing to a `Vec` never fails.");
248        }
249
250        Ok(Multiaddr { bytes: Arc::new(writer) })
251    }
252}
253
254pub struct Iter<'a>(&'a [u8]);
256
257impl<'a> Iterator for Iter<'a> {
258    type Item = Protocol<'a>;
259
260    fn next(&mut self) -> Option<Self::Item> {
261        if self.0.is_empty() {
262            return None;
263        }
264
265        let (p, next_data) =
266            Protocol::from_bytes(self.0).expect("`Multiaddr` is known to be valid.");
267
268        self.0 = next_data;
269        Some(p)
270    }
271}
272
273impl<'a> From<Protocol<'a>> for Multiaddr {
274    fn from(p: Protocol<'a>) -> Multiaddr {
275        let mut w = Vec::new();
276        p.write_bytes(&mut w).expect("Writing to a `Vec` never fails.");
277        Multiaddr { bytes: Arc::new(w) }
278    }
279}
280
281impl From<IpAddr> for Multiaddr {
282    fn from(v: IpAddr) -> Multiaddr {
283        match v {
284            IpAddr::V4(a) => a.into(),
285            IpAddr::V6(a) => a.into()
286        }
287    }
288}
289
290impl From<Ipv4Addr> for Multiaddr {
291    fn from(v: Ipv4Addr) -> Multiaddr {
292        Protocol::Ip4(v).into()
293    }
294}
295
296impl From<Ipv6Addr> for Multiaddr {
297    fn from(v: Ipv6Addr) -> Multiaddr {
298        Protocol::Ip6(v).into()
299    }
300}
301
302impl TryFrom<Vec<u8>> for Multiaddr {
303    type Error = Error;
304
305    fn try_from(v: Vec<u8>) -> Result<Self> {
306        let mut slice = &v[..];
308        while !slice.is_empty() {
309            let (_, s) = Protocol::from_bytes(slice)?;
310            slice = s
311        }
312        Ok(Multiaddr { bytes: Arc::new(v) })
313    }
314}
315
316impl TryFrom<String> for Multiaddr {
317    type Error = Error;
318
319    fn try_from(s: String) -> Result<Multiaddr> {
320        s.parse()
321    }
322}
323
324impl<'a> TryFrom<&'a str> for Multiaddr {
325    type Error = Error;
326
327    fn try_from(s: &'a str) -> Result<Multiaddr> {
328        s.parse()
329    }
330}
331
332impl Serialize for Multiaddr {
333    fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
334    where
335        S: Serializer,
336    {
337        if serializer.is_human_readable() {
338            serializer.serialize_str(&self.to_string())
339        } else {
340            serializer.serialize_bytes(self.as_ref())
341        }
342    }
343}
344
345impl<'de> Deserialize<'de> for Multiaddr {
346    fn deserialize<D>(deserializer: D) -> StdResult<Self, D::Error>
347    where
348        D: Deserializer<'de>,
349    {
350        struct Visitor { is_human_readable: bool };
351
352        impl<'de> de::Visitor<'de> for Visitor {
353            type Value = Multiaddr;
354
355            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
356                formatter.write_str("multiaddress")
357            }
358            fn visit_seq<A: de::SeqAccess<'de>>(self, mut seq: A) -> StdResult<Self::Value, A::Error> {
359                let mut buf: Vec<u8> = Vec::with_capacity(std::cmp::min(seq.size_hint().unwrap_or(0), 4096));
360                while let Some(e) = seq.next_element()? { buf.push(e); }
361                if self.is_human_readable {
362                    let s = String::from_utf8(buf).map_err(DeserializerError::custom)?;
363                    s.parse().map_err(DeserializerError::custom)
364                } else {
365                    Multiaddr::try_from(buf).map_err(DeserializerError::custom)
366                }
367            }
368            fn visit_str<E: de::Error>(self, v: &str) -> StdResult<Self::Value, E> {
369                v.parse().map_err(DeserializerError::custom)
370            }
371            fn visit_borrowed_str<E: de::Error>(self, v: &'de str) -> StdResult<Self::Value, E> {
372                self.visit_str(v)
373            }
374            fn visit_string<E: de::Error>(self, v: String) -> StdResult<Self::Value, E> {
375                self.visit_str(&v)
376            }
377            fn visit_bytes<E: de::Error>(self, v: &[u8]) -> StdResult<Self::Value, E> {
378                self.visit_byte_buf(v.into())
379            }
380            fn visit_borrowed_bytes<E: de::Error>(self, v: &'de [u8]) -> StdResult<Self::Value, E> {
381                self.visit_byte_buf(v.into())
382            }
383            fn visit_byte_buf<E: de::Error>(self, v: Vec<u8>) -> StdResult<Self::Value, E> {
384                Multiaddr::try_from(v).map_err(DeserializerError::custom)
385            }
386        }
387
388        if deserializer.is_human_readable() {
389            deserializer.deserialize_str(Visitor { is_human_readable: true })
390        } else {
391            deserializer.deserialize_bytes(Visitor { is_human_readable: false })
392        }
393    }
394}
395
396#[macro_export]
410macro_rules! multiaddr {
411    ($($comp:ident $(($param:expr))*),+) => {
412        {
413            use std::iter;
414            let elem = iter::empty::<$crate::Protocol>();
415            $(
416                let elem = {
417                    let cmp = $crate::Protocol::$comp $(( $param.into() ))*;
418                    elem.chain(iter::once(cmp))
419                };
420            )+
421            elem.collect::<$crate::Multiaddr>()
422        }
423    }
424}