network/fundamentals/
cidr.rs

1use core::fmt::{Debug, Display};
2
3use crate::{Ipv4, Ipv6};
4
5#[repr(C)]
6#[derive(Default, Clone, PartialEq, Eq)]
7pub struct Cidr<T: Default + Clone + PartialEq + Eq> {
8    pub address: T,
9    pub prefix_length: u8,
10}
11
12impl<T: Debug + Default + Clone + PartialEq + Eq> Cidr<T> {
13    pub const fn new(address: T, prefix_length: u8) -> Self {
14        Self {
15            address,
16            prefix_length,
17        }
18    }
19}
20
21impl<T: Debug + Default + Clone + PartialEq + Eq> Debug for Cidr<T> {
22    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
23        write!(f, "{:?}/{}", self.address, self.prefix_length)
24    }
25}
26
27impl<T: Display + Default + Clone + PartialEq + Eq> Display for Cidr<T> {
28    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
29        write!(f, "{}/{}", self.address, self.prefix_length)
30    }
31}
32
33impl Cidr<Ipv4> {
34    pub const fn into_smoltcp(&self) -> smoltcp::wire::Ipv4Cidr {
35        smoltcp::wire::Ipv4Cidr::new(self.address.into_smoltcp(), self.prefix_length)
36    }
37
38    pub const fn from_smoltcp(value: &smoltcp::wire::Ipv4Cidr) -> Self {
39        Self {
40            address: Ipv4::from_smoltcp(&value.address()),
41            prefix_length: value.prefix_len(),
42        }
43    }
44}
45
46impl Cidr<Ipv6> {
47    pub const fn into_smoltcp(&self) -> smoltcp::wire::Ipv6Cidr {
48        smoltcp::wire::Ipv6Cidr::new(self.address.into_smoltcp(), self.prefix_length)
49    }
50
51    pub const fn from_smoltcp(value: &smoltcp::wire::Ipv6Cidr) -> Self {
52        Self {
53            address: Ipv6::from_smoltcp(&value.address()),
54            prefix_length: value.prefix_len(),
55        }
56    }
57}
58
59#[repr(C)]
60#[derive(Debug, Clone, PartialEq, Eq)]
61pub enum IpCidr {
62    IPv4(Cidr<Ipv4>),
63    IPv6(Cidr<Ipv6>),
64}
65
66impl Default for IpCidr {
67    fn default() -> Self {
68        IpCidr::IPv4(Cidr::default())
69    }
70}
71
72impl IpCidr {
73    pub const fn new_ipv4(address: [u8; 4], prefix_length: u8) -> Self {
74        IpCidr::IPv4(Cidr::new(Ipv4::new(address), prefix_length))
75    }
76
77    pub const fn new_ipv6(address: [u16; 8], prefix_length: u8) -> Self {
78        IpCidr::IPv6(Cidr::new(Ipv6::new(address), prefix_length))
79    }
80
81    pub const fn into_smoltcp(&self) -> smoltcp::wire::IpCidr {
82        match self {
83            IpCidr::IPv4(cidr) => smoltcp::wire::IpCidr::Ipv4(cidr.into_smoltcp()),
84            IpCidr::IPv6(cidr) => smoltcp::wire::IpCidr::Ipv6(cidr.into_smoltcp()),
85        }
86    }
87
88    pub const fn from_smoltcp(value: &smoltcp::wire::IpCidr) -> Self {
89        match value {
90            smoltcp::wire::IpCidr::Ipv4(cidr) => IpCidr::IPv4(Cidr::<Ipv4>::from_smoltcp(cidr)),
91            smoltcp::wire::IpCidr::Ipv6(cidr) => IpCidr::IPv6(Cidr::<Ipv6>::from_smoltcp(cidr)),
92        }
93    }
94}
95
96impl Display for IpCidr {
97    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
98        match self {
99            IpCidr::IPv4(cidr) => write!(f, "{cidr}"),
100            IpCidr::IPv6(cidr) => write!(f, "{cidr}"),
101        }
102    }
103}