use core::{
fmt::{Debug, Display, Formatter},
str::FromStr,
};
#[derive(
derive_more::From,
derive_more::Into,
derive_more::Deref,
Copy,
Clone,
Debug,
Hash,
Eq,
PartialEq,
serde::Serialize,
serde::Deserialize,
)]
pub struct CidrBlock(pub [u8; 5]);
#[derive(Debug, Clone)]
pub struct CidrBlockParseErr;
impl FromStr for CidrBlock {
type Err = CidrBlockParseErr;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let ip_and_suffix: Vec<&str> = s.split('/').collect();
if ip_and_suffix.len() != 2 {
return Err(CidrBlockParseErr);
}
let mut cidr_block_strings: Vec<&str> = ip_and_suffix[0].split('.').collect();
if cidr_block_strings.len() != 4 {
return Err(CidrBlockParseErr);
}
cidr_block_strings.push(ip_and_suffix[1]);
let mut array = [0_u8; 5];
for i in 0..array.len() {
array[i] = match cidr_block_strings[i].parse().ok() {
Some(x) => x,
None => return Err(CidrBlockParseErr),
}
}
Ok(array.into())
}
}
impl Display for CidrBlock {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(
f,
"{}.{}.{}.{}/{}",
self[0], self[1], self[2], self[3], self[4]
)
}
}
#[test]
fn test_convert_cidr_block_to_string() {
let block: CidrBlock = [1, 2, 3, 4, 5].into();
let converted = block.to_string();
assert_eq!(converted, "1.2.3.4/5");
}