ip/concrete/addr/
ipv4.rs

1use super::Address;
2use crate::{
3    concrete::{Ipv4, Ipv6},
4    traits::{primitive::Address as _, Afi},
5};
6
7// TODO: make methods `const fn`
8impl Address<Ipv4> {
9    /// The IPv4 subnet-local broadcast address `255.255.255.255`.
10    pub const BROADCAST: Self = {
11        if let Some(inner) = <Ipv4 as Afi>::Primitive::BROADCAST {
12            Self::new(inner)
13        } else {
14            panic!("failed to get BROADCAST address value")
15        }
16    };
17
18    /// Converts this [`Address<Ipv4>`] to an IPv4-compatible
19    /// [`Address<Ipv6>`].
20    ///
21    /// IPv4-compatible IPv6 addresses are of the form `::a.b.c.d`, where
22    /// `a.b.c.d` is the corresponding IPv4 address. See [RFC 4291].
23    ///
24    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
25    ///
26    /// # Examples
27    ///
28    /// ``` rust
29    /// use ip::{Address, Ipv4, Ipv6};
30    ///
31    /// assert_eq!(
32    ///     "172.16.12.1".parse::<Address<Ipv4>>()?.to_ipv6_compatible(),
33    ///     "::172.16.12.1".parse::<Address<Ipv6>>()?,
34    /// );
35    /// # Ok::<(), ip::Error>(())
36    /// ```
37    #[allow(clippy::wrong_self_convention)]
38    #[must_use]
39    pub fn to_ipv6_compatible(&self) -> Address<Ipv6> {
40        Address::from_octets(self.to_ipv6_lo_octets())
41    }
42
43    /// Converts this [`Address<Ipv4>`] to an IPv4-mapped [`Address<Ipv6>`].
44    ///
45    /// IPv4-mapped IPv6 addresses are of the form `::ffff:a.b.c.d`, where
46    /// `a.b.c.d` is the corresponding IPv4 address. See [RFC 4291].
47    ///
48    /// [RFC 4291]: https://tools.ietf.org/html/rfc4291
49    ///
50    /// # Examples
51    ///
52    /// ``` rust
53    /// use ip::{Address, Ipv4, Ipv6};
54    ///
55    /// assert_eq!(
56    ///     "172.16.12.1".parse::<Address<Ipv4>>()?.to_ipv6_mapped(),
57    ///     "::ffff:172.16.12.1".parse::<Address<Ipv6>>()?,
58    /// );
59    /// # Ok::<(), ip::Error>(())
60    /// ```
61    #[allow(clippy::wrong_self_convention)]
62    #[must_use]
63    pub fn to_ipv6_mapped(&self) -> Address<Ipv6> {
64        let mut octets = self.to_ipv6_lo_octets();
65        octets[10..12].copy_from_slice(&[0xffu8, 0xffu8]);
66        Address::from_octets(octets)
67    }
68
69    fn to_ipv6_lo_octets(self) -> <Ipv6 as Afi>::Octets {
70        let mut octets = <Ipv6 as Afi>::Octets::default();
71        octets[12..].copy_from_slice(&self.octets());
72        octets
73    }
74}