iptrie/prefix/
ipv6netaddr.rs

1
2use std::fmt;
3use std::fmt::{Debug, Display};
4use std::net::Ipv6Addr;
5use std::str::FromStr;
6use ipnet::Ipv6Net;
7use crate::{IpPrefix, IpPrefixError, Ipv6Prefix, Ipv6Prefix120};
8
9/// An Ipv6 prefix of fixed length of 64 bits
10///
11/// This prefix is commonly used to carry the network
12/// address of a unicast Ipv6 address.
13/// It takes exactly 64 bits.
14/// ```text
15/// |------------ 64 bits ---------------|
16///            ip prefix slot
17/// ```
18/// To deal with a short prefix but without a fixed length,
19/// consider [`Ipv6Prefix56`] which use one char to
20/// store its length.
21#[repr(C)]
22#[derive(Copy, Clone, Eq, PartialEq, Hash)]
23pub struct Ipv6NetAddr {
24    addr: u64
25}
26
27impl IpPrefix for Ipv6NetAddr {
28    type Slot = u64;
29
30    #[inline] fn bitslot(&self) -> Self::Slot { self.addr }
31    #[inline] fn bitslot_trunc(&self) -> Self::Slot { self.addr }
32    #[inline] fn len(&self) -> u8 { 64 }
33    #[inline] fn bitmask(&self) -> Self::Slot { !0 }
34
35    const MAX_LEN: u8 = 64;
36    type Addr = Ipv6Addr;
37
38    #[inline] fn network(&self) -> Self::Addr {
39        ((self.addr as u128) << 64).into()
40    }
41}
42
43impl Ipv6NetAddr
44{
45    #[inline]
46    pub fn new(addr: Ipv6Addr) -> Self
47    {
48        Self { addr: (u128::from(addr) >> 64) as u64 }
49    }
50
51    #[inline]
52    pub fn into_slot(self) -> u64 { self.addr }
53
54    #[inline]
55    pub fn from_slot(addr: u64) -> Self { Self { addr } }
56}
57
58impl From<Ipv6NetAddr> for Ipv6Net
59{
60    #[inline] fn from(value: Ipv6NetAddr) -> Self {
61        Ipv6Net::new(value.network(), value.len()).unwrap()
62    }
63}
64
65impl From<Ipv6NetAddr> for Ipv6Prefix
66{
67    #[inline] fn from(value: Ipv6NetAddr) -> Self {
68        Ipv6Prefix::new(value.network(), value.len()).unwrap()
69    }
70}
71
72impl From<Ipv6NetAddr> for Ipv6Prefix120
73{
74    #[inline] fn from(value: Ipv6NetAddr) -> Self {
75        let slot= ((value.addr as u128) << 64) | 64;
76        unsafe { Ipv6Prefix120::from_slot_unchecked(slot) }
77    }
78}
79
80impl TryFrom<Ipv6Net> for Ipv6NetAddr
81{
82    type Error = IpPrefixError;
83    #[inline]
84    fn try_from(value: Ipv6Net) -> Result<Self, Self::Error> {
85        if value.len() == 64 {
86            Ok(Self { addr: (value.bitslot() >> 64) as u64 })
87        } else {
88            Err(IpPrefixError::PrefixLenError)
89        }
90    }
91}
92
93impl TryFrom<Ipv6Prefix> for Ipv6NetAddr
94{
95    type Error = IpPrefixError;
96    #[inline]
97    fn try_from(value: Ipv6Prefix) -> Result<Self, Self::Error> {
98        if value.len() == 64 {
99            Ok(Self { addr: (value.bitslot() >> 64) as u64 })
100        } else {
101            Err(IpPrefixError::PrefixLenError)
102        }
103    }
104}
105
106impl TryFrom<Ipv6Prefix120> for Ipv6NetAddr
107{
108    type Error = IpPrefixError;
109    #[inline]
110    fn try_from(value: Ipv6Prefix120) -> Result<Self, Self::Error> {
111        if value.len() == 64 {
112            Ok(Self { addr: (value.bitslot() >> 64) as u64 })
113        } else {
114            Err(IpPrefixError::PrefixLenError)
115        }
116    }
117}
118
119impl From<u64> for Ipv6NetAddr
120{
121    #[inline]
122    fn from(addr: u64) -> Self { Self { addr } }
123}
124
125
126impl From<Ipv6NetAddr> for u64
127{
128    #[inline]
129    fn from(addr: Ipv6NetAddr) -> u64 { addr.addr }
130}
131
132
133impl Display for Ipv6NetAddr {
134    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135        let ip = (*self).into();
136        <Ipv6Net as fmt::Display>::fmt(&ip, f)
137    }
138}
139impl Debug for Ipv6NetAddr {
140    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141        let ip = (*self).into();
142        <Ipv6Net as fmt::Display>::fmt(&ip, f)
143    }
144}
145impl FromStr for Ipv6NetAddr {
146    type Err = IpPrefixError;
147    fn from_str(s: &str) -> Result<Self, Self::Err> {
148        Self::try_from(Ipv6Net::from_str(s)?)
149    }
150}