1#[cfg(feature = "bitstring")]
2#[cfg_attr(doc_cfg, doc(cfg(feature = "bitstring")))]
3use bitstring::FixedBitString;
4
5use core::{
6 fmt,
7 str::FromStr,
8};
9use std::net::{
10 Ipv4Addr,
11 Ipv6Addr,
12};
13
14use super::from_str::inet_from_str;
15use crate::{
16 errors::*,
17 internal_traits::{
18 PrivInet,
19 PrivUnspecAddress,
20 },
21 Family,
22 Inet,
23 Ipv4Cidr,
24 Ipv4Inet,
25 Ipv6Cidr,
26 Ipv6Inet,
27};
28
29macro_rules! impl_inet_for {
30 ($n:ident : cidr $cidr:ident : addr $addr:ident : pair $pair:ident : family $family:expr) => {
31 #[cfg(feature = "bitstring")]
32 #[cfg_attr(doc_cfg, doc(cfg(feature = "bitstring")))]
33 impl bitstring::BitString for $n {
34 fn get(&self, ndx: usize) -> bool {
35 self.address.get(ndx)
36 }
37
38 fn set(&mut self, ndx: usize, bit: bool) {
39 assert!(ndx < self.network_length as usize);
40 self.address.set(ndx, bit);
41 }
42
43 fn flip(&mut self, ndx: usize) {
44 assert!(ndx < self.network_length as usize);
45 self.address.flip(ndx);
46 }
47
48 fn len(&self) -> usize {
49 self.network_length as usize
50 }
51
52 fn clip(&mut self, len: usize) {
53 if len > 255 {
54 return;
55 }
56 self.address.set_false_from(len);
57 self.network_length = core::cmp::min(self.network_length, len as u8);
58 }
59
60 fn append(&mut self, bit: bool) {
61 self.address.set(self.network_length as usize, bit);
62 self.network_length += 1;
63 }
64
65 fn null() -> Self {
66 Self {
67 address: FixedBitString::new_all_false(),
68 network_length: 0,
69 }
70 }
71
72 fn shared_prefix_len(&self, other: &Self) -> usize {
73 let max_len = core::cmp::min(self.network_length, other.network_length) as usize;
74 FixedBitString::shared_prefix_len(&self.address, &other.address, max_len)
75 }
76 }
77
78 impl $n {
79 pub const fn new(addr: $addr, len: u8) -> Result<Self, NetworkLengthTooLongError> {
83 if len > $family.len() {
84 Err(NetworkLengthTooLongError::new(len as usize, $family))
85 } else {
86 Ok(Self {
87 address: addr,
88 network_length: len,
89 })
90 }
91 }
92
93 pub const fn new_host(addr: $addr) -> Self {
96 Self {
97 address: addr,
98 network_length: $family.len(),
99 }
100 }
101
102 pub fn increment(&mut self) -> bool {
105 let (address, overflow) = <$addr as PrivUnspecAddress>::_Tools::_overflowing_next(
106 self.address,
107 self.network_length,
108 );
109 self.address = address;
110 overflow
111 }
112
113 pub const fn next(self) -> Option<Self> {
115 let (address, overflow) = <$addr as PrivUnspecAddress>::_Tools::_overflowing_next(
116 self.address,
117 self.network_length,
118 );
119 if overflow {
120 None
121 } else {
122 Some(Self {
123 address,
124 network_length: self.network_length,
125 })
126 }
127 }
128
129 pub fn decrement(&mut self) -> bool {
132 let (address, overflow) = <$addr as PrivUnspecAddress>::_Tools::_overflowing_prev(
133 self.address,
134 self.network_length,
135 );
136 self.address = address;
137 overflow
138 }
139
140 pub const fn previous(self) -> Option<Self> {
142 let (address, overflow) = <$addr as PrivUnspecAddress>::_Tools::_overflowing_prev(
143 self.address,
144 self.network_length,
145 );
146 if overflow {
147 None
148 } else {
149 Some(Self {
150 address,
151 network_length: self.network_length,
152 })
153 }
154 }
155
156 pub const fn overflowing_add(self, step: u128) -> (Self, bool) {
160 let (address, overflow) = <$addr as PrivUnspecAddress>::_Tools::_overflowing_inc(
161 self.address,
162 self.network_length,
163 step,
164 );
165 (
166 Self {
167 address,
168 network_length: self.network_length,
169 },
170 overflow,
171 )
172 }
173
174 pub const fn overflowing_sub(self, step: u128) -> (Self, bool) {
178 let (address, overflow) = <$addr as PrivUnspecAddress>::_Tools::_overflowing_dec(
179 self.address,
180 self.network_length,
181 step,
182 );
183 (
184 Self {
185 address,
186 network_length: self.network_length,
187 },
188 overflow,
189 )
190 }
191
192 pub const fn network(&self) -> $cidr {
194 $cidr {
195 address: self.first_address(),
196 network_length: self.network_length,
197 }
198 }
199
200 pub const fn address(&self) -> $addr {
202 self.address
203 }
204
205 pub const fn first_address(&self) -> $addr {
207 <$addr as PrivUnspecAddress>::_Tools::_network_address(
208 self.address,
209 self.network_length,
210 )
211 }
212
213 pub const fn first(&self) -> Self {
215 Self {
216 address: self.first_address(),
217 network_length: self.network_length,
218 }
219 }
220
221 pub const fn last_address(&self) -> $addr {
223 <$addr as PrivUnspecAddress>::_Tools::_last_address(
224 self.address,
225 self.network_length,
226 )
227 }
228
229 pub const fn last(&self) -> Self {
231 Self {
232 address: self.last_address(),
233 network_length: self.network_length,
234 }
235 }
236
237 pub const fn network_length(&self) -> u8 {
239 self.network_length
240 }
241
242 pub const fn family(&self) -> Family {
247 $family
248 }
249
250 pub const fn is_host_address(&self) -> bool {
252 self.network_length() == self.family().len()
253 }
254
255 pub const fn mask(&self) -> $addr {
258 <$addr as PrivUnspecAddress>::_Tools::_network_mask(self.network_length)
259 }
260
261 pub const fn contains(&self, addr: &$addr) -> bool {
263 <$addr as PrivUnspecAddress>::_Tools::_prefix_match(
264 self.address,
265 *addr,
266 self.network_length,
267 )
268 }
269 }
270
271 impl PrivInet for $n {}
272
273 impl Inet for $n {
274 type Address = $addr;
275
276 fn new(addr: $addr, len: u8) -> Result<Self, NetworkLengthTooLongError> {
277 Self::new(addr, len)
278 }
279
280 fn new_host(addr: $addr) -> Self {
281 Self::new_host(addr)
282 }
283
284 fn increment(&mut self) -> bool {
285 self.increment()
286 }
287
288 fn next(self) -> Option<Self> {
289 self.next()
290 }
291
292 fn decrement(&mut self) -> bool {
293 self.decrement()
294 }
295
296 fn previous(self) -> Option<Self> {
297 self.previous()
298 }
299
300 fn overflowing_add(self, step: u128) -> (Self, bool) {
301 self.overflowing_add(step)
302 }
303
304 fn overflowing_sub(self, step: u128) -> (Self, bool) {
305 self.overflowing_sub(step)
306 }
307
308 fn network(&self) -> $cidr {
309 self.network()
310 }
311
312 fn address(&self) -> $addr {
313 self.address()
314 }
315
316 fn first_address(&self) -> $addr {
317 self.first_address()
318 }
319
320 fn first(&self) -> Self {
321 self.first()
322 }
323
324 fn last_address(&self) -> $addr {
325 self.last_address()
326 }
327
328 fn last(&self) -> Self {
329 self.last()
330 }
331
332 fn network_length(&self) -> u8 {
333 self.network_length()
334 }
335
336 fn family(&self) -> Family {
337 self.family()
338 }
339
340 fn is_host_address(&self) -> bool {
341 self.is_host_address()
342 }
343
344 fn mask(&self) -> $addr {
345 self.mask()
346 }
347
348 fn contains(&self, addr: &$addr) -> bool {
349 self.contains(addr)
350 }
351 }
352
353 impl fmt::Debug for $n {
354 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
355 write!(f, "{:?}/{}", self.address, self.network_length)
356 }
357 }
358
359 impl fmt::Display for $n {
360 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
361 if f.alternate() || !self.is_host_address() {
362 write!(f, "{}/{}", self.address, self.network_length)?;
363 } else {
364 write!(f, "{}", self.address)?;
365 }
366 Ok(())
367 }
368 }
369
370 impl FromStr for $n {
371 type Err = NetworkParseError;
372
373 fn from_str(s: &str) -> Result<Self, NetworkParseError> {
374 inet_from_str(s)
375 }
376 }
377
378 impl core::ops::Add<u128> for $n {
379 type Output = $n;
380
381 fn add(self, step: u128) -> Self::Output {
382 let (result, overflow) = self.overflowing_add(step);
383 debug_assert!(!overflow, "{} + {} overflow", self, step);
384 result
385 }
386 }
387
388 impl core::ops::Sub<u128> for $n {
389 type Output = $n;
390
391 fn sub(self, step: u128) -> Self::Output {
392 let (result, overflow) = self.overflowing_sub(step);
393 debug_assert!(!overflow, "{} - {} overflow", self, step);
394 result
395 }
396 }
397 };
398}
399
400impl_inet_for! {Ipv4Inet : cidr Ipv4Cidr : addr Ipv4Addr : pair Ipv4InetPair : family Family::Ipv4}
401impl_inet_for! {Ipv6Inet : cidr Ipv6Cidr : addr Ipv6Addr : pair Ipv6InetPair : family Family::Ipv6}
402
403impl Ipv4Inet {
404 pub const fn overflowing_add_u32(self, step: u32) -> (Self, bool) {
408 let (address, overflow) = <Ipv4Addr as PrivUnspecAddress>::_Tools::_overflowing_inc_u32(
409 self.address,
410 self.network_length,
411 step,
412 );
413 (
414 Self {
415 address,
416 network_length: self.network_length,
417 },
418 overflow,
419 )
420 }
421
422 pub const fn overflowing_sub_u32(self, step: u32) -> (Self, bool) {
426 let (address, overflow) = <Ipv4Addr as PrivUnspecAddress>::_Tools::_overflowing_dec_u32(
427 self.address,
428 self.network_length,
429 step,
430 );
431 (
432 Self {
433 address,
434 network_length: self.network_length,
435 },
436 overflow,
437 )
438 }
439}
440
441impl core::ops::Add<u32> for Ipv4Inet {
442 type Output = Ipv4Inet;
443
444 fn add(self, step: u32) -> Self::Output {
445 let (result, overflow) = self.overflowing_add_u32(step);
446 debug_assert!(!overflow, "{} + {} overflow", self, step);
447 result
448 }
449}
450
451impl core::ops::Sub<u32> for Ipv4Inet {
452 type Output = Ipv4Inet;
453
454 fn sub(self, step: u32) -> Self::Output {
455 let (result, overflow) = self.overflowing_sub_u32(step);
456 debug_assert!(!overflow, "{} - {} overflow", self, step);
457 result
458 }
459}