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::PrivInet,
14 Family,
15 Inet,
16 IpCidr,
17 IpInet,
18 Ipv4Inet,
19 Ipv6Inet,
20};
21
22impl IpInet {
23 pub const fn is_ipv4(&self) -> bool {
25 match self {
26 Self::V4(_) => true,
27 Self::V6(_) => false,
28 }
29 }
30
31 pub const fn is_ipv6(&self) -> bool {
33 match self {
34 Self::V4(_) => false,
35 Self::V6(_) => true,
36 }
37 }
38
39 pub const fn new(addr: IpAddr, len: u8) -> Result<Self, NetworkLengthTooLongError> {
45 match addr {
46 IpAddr::V4(a) => match Ipv4Inet::new(a, len) {
47 Ok(inet) => Ok(Self::V4(inet)),
48 Err(e) => Err(e),
49 },
50 IpAddr::V6(a) => match Ipv6Inet::new(a, len) {
51 Ok(inet) => Ok(Self::V6(inet)),
52 Err(e) => Err(e),
53 },
54 }
55 }
56
57 pub const fn new_host(addr: IpAddr) -> Self {
60 match addr {
61 IpAddr::V4(a) => Self::V4(Ipv4Inet::new_host(a)),
62 IpAddr::V6(a) => Self::V6(Ipv6Inet::new_host(a)),
63 }
64 }
65
66 pub fn increment(&mut self) -> bool {
69 match self {
70 Self::V4(mut c) => c.increment(),
71 Self::V6(mut c) => c.increment(),
72 }
73 }
74
75 pub const fn next(self) -> Option<Self> {
77 match self {
78 Self::V4(c) => match c.next() {
79 Some(c) => Some(Self::V4(c)),
80 None => None,
81 },
82 Self::V6(c) => match c.next() {
83 Some(c) => Some(Self::V6(c)),
84 None => None,
85 },
86 }
87 }
88
89 pub fn decrement(&mut self) -> bool {
92 match self {
93 Self::V4(mut c) => c.decrement(),
94 Self::V6(mut c) => c.decrement(),
95 }
96 }
97
98 pub const fn previous(self) -> Option<Self> {
100 match self {
101 Self::V4(c) => match c.previous() {
102 Some(c) => Some(Self::V4(c)),
103 None => None,
104 },
105 Self::V6(c) => match c.previous() {
106 Some(c) => Some(Self::V6(c)),
107 None => None,
108 },
109 }
110 }
111
112 pub const fn overflowing_add(self, step: u128) -> (Self, bool) {
116 match self {
117 Self::V4(c) => {
118 let (c, overflow) = c.overflowing_add(step);
119 (Self::V4(c), overflow)
120 },
121 Self::V6(c) => {
122 let (c, overflow) = c.overflowing_add(step);
123 (Self::V6(c), overflow)
124 },
125 }
126 }
127
128 pub const fn overflowing_sub(self, step: u128) -> (Self, bool) {
132 match self {
133 Self::V4(c) => {
134 let (c, overflow) = c.overflowing_sub(step);
135 (Self::V4(c), overflow)
136 },
137 Self::V6(c) => {
138 let (c, overflow) = c.overflowing_sub(step);
139 (Self::V6(c), overflow)
140 },
141 }
142 }
143
144 pub const fn network(&self) -> IpCidr {
146 match self {
147 Self::V4(c) => IpCidr::V4(c.network()),
148 Self::V6(c) => IpCidr::V6(c.network()),
149 }
150 }
151
152 pub const fn address(&self) -> IpAddr {
154 match self {
155 Self::V4(c) => IpAddr::V4(c.address()),
156 Self::V6(c) => IpAddr::V6(c.address()),
157 }
158 }
159
160 pub const fn first_address(&self) -> IpAddr {
162 match self {
163 Self::V4(c) => IpAddr::V4(c.first_address()),
164 Self::V6(c) => IpAddr::V6(c.first_address()),
165 }
166 }
167
168 pub const fn first(&self) -> Self {
170 match self {
171 Self::V4(c) => Self::V4(c.first()),
172 Self::V6(c) => Self::V6(c.first()),
173 }
174 }
175
176 pub const fn last_address(&self) -> IpAddr {
178 match self {
179 Self::V4(c) => IpAddr::V4(c.last_address()),
180 Self::V6(c) => IpAddr::V6(c.last_address()),
181 }
182 }
183
184 pub const fn last(&self) -> Self {
186 match self {
187 Self::V4(c) => Self::V4(c.last()),
188 Self::V6(c) => Self::V6(c.last()),
189 }
190 }
191
192 pub const fn network_length(&self) -> u8 {
194 match self {
195 Self::V4(c) => c.network_length(),
196 Self::V6(c) => c.network_length(),
197 }
198 }
199
200 pub const fn family(&self) -> Family {
205 match self {
206 Self::V4(_) => Family::Ipv4,
207 Self::V6(_) => Family::Ipv6,
208 }
209 }
210
211 pub const fn is_host_address(&self) -> bool {
213 match self {
214 Self::V4(c) => c.is_host_address(),
215 Self::V6(c) => c.is_host_address(),
216 }
217 }
218
219 pub const fn mask(&self) -> IpAddr {
222 match self {
223 Self::V4(c) => IpAddr::V4(c.mask()),
224 Self::V6(c) => IpAddr::V6(c.mask()),
225 }
226 }
227
228 pub const fn contains(&self, addr: &IpAddr) -> bool {
230 match self {
231 Self::V4(c) => match addr {
232 IpAddr::V4(a) => c.contains(a),
233 IpAddr::V6(_) => false,
234 },
235 Self::V6(c) => match addr {
236 IpAddr::V4(_) => false,
237 IpAddr::V6(a) => c.contains(a),
238 },
239 }
240 }
241}
242
243impl PrivInet for IpInet {}
244
245impl Inet for IpInet {
246 type Address = IpAddr;
247
248 fn new(addr: IpAddr, len: u8) -> Result<Self, NetworkLengthTooLongError> {
249 Self::new(addr, len)
250 }
251
252 fn new_host(addr: IpAddr) -> Self {
253 Self::new_host(addr)
254 }
255
256 fn increment(&mut self) -> bool {
257 self.increment()
258 }
259
260 fn next(self) -> Option<Self> {
261 self.next()
262 }
263
264 fn decrement(&mut self) -> bool {
265 self.decrement()
266 }
267
268 fn previous(self) -> Option<Self> {
269 self.previous()
270 }
271
272 fn overflowing_add(self, step: u128) -> (Self, bool) {
273 self.overflowing_add(step)
274 }
275
276 fn overflowing_sub(self, step: u128) -> (Self, bool) {
277 self.overflowing_sub(step)
278 }
279
280 fn network(&self) -> IpCidr {
281 self.network()
282 }
283
284 fn address(&self) -> IpAddr {
285 self.address()
286 }
287
288 fn first_address(&self) -> IpAddr {
289 self.first_address()
290 }
291
292 fn first(&self) -> Self {
293 self.first()
294 }
295
296 fn last_address(&self) -> IpAddr {
297 self.last_address()
298 }
299
300 fn last(&self) -> Self {
301 self.last()
302 }
303
304 fn network_length(&self) -> u8 {
305 self.network_length()
306 }
307
308 fn family(&self) -> Family {
309 self.family()
310 }
311
312 fn is_host_address(&self) -> bool {
313 self.is_host_address()
314 }
315
316 fn mask(&self) -> IpAddr {
317 self.mask()
318 }
319
320 fn contains(&self, addr: &IpAddr) -> bool {
321 self.contains(addr)
322 }
323}
324
325impl fmt::Display for IpInet {
326 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
327 match self {
328 Self::V4(c) => fmt::Display::fmt(c, f),
329 Self::V6(c) => fmt::Display::fmt(c, f),
330 }
331 }
332}
333
334impl FromStr for IpInet {
335 type Err = NetworkParseError;
336
337 fn from_str(s: &str) -> Result<Self, NetworkParseError> {
338 crate::parsers::parse_inet(s, FromStr::from_str)
339 }
340}
341
342impl From<Ipv4Inet> for IpInet {
343 fn from(c: Ipv4Inet) -> Self {
344 Self::V4(c)
345 }
346}
347
348impl From<Ipv4Addr> for IpInet {
349 fn from(adress: Ipv4Addr) -> Self {
350 Self::V4(adress.into())
351 }
352}
353
354impl From<Ipv6Inet> for IpInet {
355 fn from(c: Ipv6Inet) -> Self {
356 Self::V6(c)
357 }
358}
359
360impl From<Ipv6Addr> for IpInet {
361 fn from(address: Ipv6Addr) -> Self {
362 Self::V6(address.into())
363 }
364}
365
366impl From<IpAddr> for IpInet {
367 fn from(address: IpAddr) -> Self {
368 Self::new_host(address)
369 }
370}
371
372impl core::ops::Add<u128> for IpInet {
373 type Output = IpInet;
374
375 fn add(self, step: u128) -> Self::Output {
376 let (result, overflow) = self.overflowing_add(step);
377 debug_assert!(!overflow, "{} + {} overflow", self, step);
378 result
379 }
380}
381
382impl core::ops::Sub<u128> for IpInet {
383 type Output = IpInet;
384
385 fn sub(self, step: u128) -> Self::Output {
386 let (result, overflow) = self.overflowing_sub(step);
387 debug_assert!(!overflow, "{} - {} overflow", self, step);
388 result
389 }
390}