network/fundamentals/
cidr.rs1use 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}