1use core::{
2 fmt,
3 net::{
4 IpAddr,
5 Ipv4Addr,
6 Ipv6Addr,
7 },
8 str::FromStr,
9};
10
11use crate::{
12 errors::*,
13 internal_traits::PrivCidr,
14 Cidr,
15 Family,
16 InetIterator,
17 IpCidr,
18 IpInet,
19 IpInetPair,
20 Ipv4Cidr,
21 Ipv6Cidr,
22};
23
24impl IpCidr {
25 pub const fn is_ipv4(&self) -> bool {
27 match self {
28 Self::V4(_) => true,
29 Self::V6(_) => false,
30 }
31 }
32
33 pub const fn is_ipv6(&self) -> bool {
35 match self {
36 Self::V4(_) => false,
37 Self::V6(_) => true,
38 }
39 }
40
41 pub const fn new(addr: IpAddr, len: u8) -> Result<Self, NetworkParseError> {
48 match addr {
49 IpAddr::V4(a) => match Ipv4Cidr::new(a, len) {
50 Ok(cidr) => Ok(Self::V4(cidr)),
51 Err(e) => Err(e),
52 },
53 IpAddr::V6(a) => match Ipv6Cidr::new(a, len) {
54 Ok(cidr) => Ok(Self::V6(cidr)),
55 Err(e) => Err(e),
56 },
57 }
58 }
59
60 pub const fn new_host(addr: IpAddr) -> Self {
63 match addr {
64 IpAddr::V4(a) => Self::V4(Ipv4Cidr::new_host(a)),
65 IpAddr::V6(a) => Self::V6(Ipv6Cidr::new_host(a)),
66 }
67 }
68
69 pub const fn iter(&self) -> InetIterator<IpAddr> {
73 self._range_pair().iter()
74 }
75
76 pub const fn first_address(&self) -> IpAddr {
78 match self {
79 Self::V4(c) => IpAddr::V4(c.first_address()),
80 Self::V6(c) => IpAddr::V6(c.first_address()),
81 }
82 }
83
84 pub const fn first(&self) -> IpInet {
86 match self {
87 Self::V4(c) => IpInet::V4(c.first()),
88 Self::V6(c) => IpInet::V6(c.first()),
89 }
90 }
91
92 pub const fn last_address(&self) -> IpAddr {
94 match self {
95 Self::V4(c) => IpAddr::V4(c.last_address()),
96 Self::V6(c) => IpAddr::V6(c.last_address()),
97 }
98 }
99
100 pub const fn last(&self) -> IpInet {
102 match self {
103 Self::V4(c) => IpInet::V4(c.last()),
104 Self::V6(c) => IpInet::V6(c.last()),
105 }
106 }
107
108 pub const fn network_length(&self) -> u8 {
110 match self {
111 Self::V4(c) => c.network_length(),
112 Self::V6(c) => c.network_length(),
113 }
114 }
115
116 pub const fn family(&self) -> Family {
121 match self {
122 Self::V4(_) => Family::Ipv4,
123 Self::V6(_) => Family::Ipv6,
124 }
125 }
126
127 pub const fn is_host_address(&self) -> bool {
129 match self {
130 Self::V4(c) => c.is_host_address(),
131 Self::V6(c) => c.is_host_address(),
132 }
133 }
134
135 pub const fn mask(&self) -> IpAddr {
138 match self {
139 Self::V4(c) => IpAddr::V4(c.mask()),
140 Self::V6(c) => IpAddr::V6(c.mask()),
141 }
142 }
143
144 pub const fn contains(&self, addr: &IpAddr) -> bool {
146 match self {
147 Self::V4(c) => match addr {
148 IpAddr::V4(a) => c.contains(a),
149 IpAddr::V6(_) => false,
150 },
151 Self::V6(c) => match addr {
152 IpAddr::V4(_) => false,
153 IpAddr::V6(a) => c.contains(a),
154 },
155 }
156 }
157
158 pub(crate) const fn _range_pair(&self) -> IpInetPair {
159 match self {
160 Self::V4(c) => IpInetPair::V4(c._range_pair()),
161 Self::V6(c) => IpInetPair::V6(c._range_pair()),
162 }
163 }
164}
165
166impl PrivCidr for IpCidr {}
167
168impl Cidr for IpCidr {
169 type Address = IpAddr;
170
171 fn new(addr: IpAddr, len: u8) -> Result<Self, NetworkParseError> {
172 Self::new(addr, len)
173 }
174
175 fn new_host(addr: IpAddr) -> Self {
176 Self::new_host(addr)
177 }
178
179 fn iter(&self) -> InetIterator<IpAddr> {
180 self.iter()
181 }
182
183 fn first_address(&self) -> IpAddr {
184 self.first_address()
185 }
186
187 fn first(&self) -> IpInet {
188 self.first()
189 }
190
191 fn last_address(&self) -> IpAddr {
192 self.last_address()
193 }
194
195 fn last(&self) -> IpInet {
196 self.last()
197 }
198
199 fn network_length(&self) -> u8 {
200 self.network_length()
201 }
202
203 fn family(&self) -> Family {
204 self.family()
205 }
206
207 fn is_host_address(&self) -> bool {
208 self.is_host_address()
209 }
210
211 fn mask(&self) -> IpAddr {
212 self.mask()
213 }
214
215 fn contains(&self, addr: &IpAddr) -> bool {
216 self.contains(addr)
217 }
218}
219
220impl fmt::Display for IpCidr {
221 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
222 match self {
223 Self::V4(c) => fmt::Display::fmt(c, f),
224 Self::V6(c) => fmt::Display::fmt(c, f),
225 }
226 }
227}
228
229impl FromStr for IpCidr {
230 type Err = NetworkParseError;
231
232 fn from_str(s: &str) -> Result<Self, NetworkParseError> {
233 crate::parsers::parse_cidr(s, FromStr::from_str)
234 }
235}
236
237impl From<Ipv4Cidr> for IpCidr {
238 fn from(c: Ipv4Cidr) -> Self {
239 Self::V4(c)
240 }
241}
242
243impl From<Ipv4Addr> for IpCidr {
244 fn from(address: Ipv4Addr) -> Self {
245 Self::V4(address.into())
246 }
247}
248
249impl From<Ipv6Cidr> for IpCidr {
250 fn from(c: Ipv6Cidr) -> Self {
251 Self::V6(c)
252 }
253}
254
255impl From<Ipv6Addr> for IpCidr {
256 fn from(address: Ipv6Addr) -> Self {
257 Self::V6(address.into())
258 }
259}
260
261impl From<IpAddr> for IpCidr {
262 fn from(address: IpAddr) -> Self {
263 Self::new_host(address)
264 }
265}
266
267impl IntoIterator for IpCidr {
268 type IntoIter = InetIterator<IpAddr>;
269 type Item = IpInet;
270
271 fn into_iter(self) -> Self::IntoIter {
272 InetIterator::_new(self._range_pair())
273 }
274}