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}