1use crate::traits::Mask;
2use std::net::Ipv6Addr;
3
4#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
10pub struct Netv6Addr {
11 addr: Ipv6Addr,
12 mask: Ipv6Addr,
13}
14
15impl Netv6Addr {
16 pub const fn mask(&self) -> Ipv6Addr {
17 self.mask
18 }
19
20 pub const fn addr(&self) -> Ipv6Addr {
21 self.addr
22 }
23
24 pub fn is_cidr(&self) -> bool {
25 let mask: u128 = self.mask.into();
26 let ones: u32 = mask.count_ones();
27 let cidr_mask: u128 = u128::max_value().checked_shl(128 - ones).unwrap_or(0);
28 mask == cidr_mask
29 }
30
31 pub fn new(addr: Ipv6Addr, mask: Ipv6Addr) -> Self {
46 let addr = addr.mask(&mask);
47 Self { addr, mask }
48 }
49}
50
51mod contains;
52mod display;
53mod from;
54mod fromstr;
55mod hash;
56mod merge;
57mod ord;
58mod partialord;
59
60#[cfg(feature = "serde")]
61mod de;
62#[cfg(feature = "serde")]
63mod ser;
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68
69 mod mask {
70 use super::*;
71
72 #[test]
73 fn returns_mask_field() {
74 let netaddr: Netv6Addr = Netv6Addr {
75 mask: "ffff:ffff:ffff:ffff::0".parse().unwrap(),
76 addr: "2001:db8:dead:beef::0".parse().unwrap(),
77 };
78
79 assert_eq!(
80 netaddr.mask(),
81 "ffff:ffff:ffff:ffff::0".parse::<Ipv6Addr>().unwrap()
82 );
83 }
84 }
85
86 mod addr {
87 use super::*;
88
89 #[test]
90 fn returns_addr_field() {
91 let netaddr: Netv6Addr = Netv6Addr {
92 mask: "ffff:ffff:ffff:ffff::0".parse().unwrap(),
93 addr: "2001:db8:dead:beef::0".parse().unwrap(),
94 };
95
96 assert_eq!(
97 netaddr.addr(),
98 "2001:db8:dead:beef::0".parse::<Ipv6Addr>().unwrap()
99 );
100 }
101 }
102
103 mod is_cidr {
104 use super::*;
105
106 #[test]
107 fn non_cidr_returns_false() {
108 let netaddr: Netv6Addr = Netv6Addr {
109 mask: "ffff:ffff:ffff:7f7f::0".parse().unwrap(),
110 addr: "::".parse().unwrap(),
111 };
112
113 assert!(!netaddr.is_cidr());
114 }
115
116 #[test]
117 fn cidr_returns_true() {
118 let netaddr: Netv6Addr = Netv6Addr {
119 mask: "ffff:ffff:ffff:fffc::0".parse().unwrap(),
120 addr: "::".parse().unwrap(),
121 };
122
123 assert!(netaddr.is_cidr());
124 }
125 }
126
127 mod new {
128 use super::*;
129
130 #[test]
131 fn masks_addr() {
132 let addr: Ipv6Addr = "2001:db8:dead:beef::0".parse().unwrap();
133 let mask: Ipv6Addr = "ffff:ffff:ffff:ff00::0".parse().unwrap();
134
135 let netaddr: Netv6Addr = Netv6Addr::new(addr, mask);
136
137 assert_eq!(netaddr.mask(), mask);
138 assert_eq!(
139 netaddr.addr(),
140 "2001:db8:dead:be00::0".parse::<Ipv6Addr>().unwrap()
141 );
142 }
143 }
144}