mm1_address/
address_range.rs1use std::fmt;
2
3use crate::address::Address;
4use crate::subnet::{NetAddress, NetMask};
5
6#[derive(Debug, Clone, Copy)]
16pub struct AddressRange {
17 lo: Address,
18 hi: Address,
19}
20
21impl AddressRange {
22 pub fn lo(&self) -> Address {
23 self.lo
24 }
25
26 pub fn hi(&self) -> Address {
27 self.hi
28 }
29}
30
31impl From<Address> for AddressRange {
32 fn from(addr: Address) -> Self {
33 Self { lo: addr, hi: addr }
34 }
35}
36impl From<NetAddress> for AddressRange {
37 fn from(net: NetAddress) -> Self {
38 let lo = net.address;
39 let hi = Address::from_u64(net.address.into_u64() | !net.mask.into_u64());
40
41 Self { lo, hi }
42 }
43}
44
45impl From<AddressRange> for NetAddress {
46 fn from(range: AddressRange) -> Self {
47 let AddressRange { lo, hi } = range;
48 let address = lo;
49 let mask_bits = !(lo.into_u64() ^ hi.into_u64());
50 let mask = NetMask::try_from(mask_bits.leading_ones() as u8).expect("should be fine");
51 Self { address, mask }
52 }
53}
54
55impl Ord for AddressRange {
56 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
57 use std::cmp::Ordering::*;
58
59 assert!(self.lo <= self.hi);
60 assert!(other.lo <= other.hi);
61
62 match (self.hi.cmp(&other.lo), self.lo.cmp(&other.hi)) {
63 (Less, Less) => Less,
64 (Greater, Greater) => Greater,
65 (..) => Equal,
66 }
67 }
68}
69impl PartialEq for AddressRange {
70 fn eq(&self, other: &Self) -> bool {
71 Ord::cmp(self, other).is_eq()
72 }
73}
74impl Eq for AddressRange {}
75impl PartialOrd for AddressRange {
76 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
77 Some(Ord::cmp(self, other))
78 }
79}
80
81impl fmt::Display for AddressRange {
82 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83 write!(f, "{}-{}", self.lo, self.hi)
84 }
85}