pub fn ipv4_to_string(addr: u32) -> Option<String> {
Some(std::net::Ipv4Addr::from(addr.to_be_bytes()).to_string())
}
pub fn ipv6_to_string(bytes: &[u8]) -> Option<String> {
if bytes.len() != 16 {
return None;
}
let bytes_array: [u8; 16] = bytes.try_into().ok()?;
Some(std::net::Ipv6Addr::from(bytes_array).to_string())
}
#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod tests {
use super::*;
#[test]
fn test_ipv4_to_string() {
assert_eq!(ipv4_to_string(0x7f000001), Some("127.0.0.1".to_string()));
assert_eq!(ipv4_to_string(0xc0a80101), Some("192.168.1.1".to_string()));
assert_eq!(ipv4_to_string(0x0a000001), Some("10.0.0.1".to_string()));
}
#[test]
fn test_ipv6_to_string_localhost() {
let localhost = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
assert_eq!(ipv6_to_string(&localhost), Some("::1".to_string()));
}
#[test]
fn test_ipv6_to_string_all_zeros() {
let all_zeros = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
assert_eq!(ipv6_to_string(&all_zeros), Some("::".to_string()));
}
#[test]
fn test_ipv6_to_string_documentation_prefix() {
let doc_addr = [0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
assert_eq!(ipv6_to_string(&doc_addr), Some("2001:db8::1".to_string()));
}
#[test]
fn test_ipv6_to_string_link_local() {
let link_local = [0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
assert_eq!(ipv6_to_string(&link_local), Some("fe80::1".to_string()));
}
#[test]
fn test_ipv6_to_string_no_compression() {
let no_zeros = [0x20, 0x01, 0x0d, 0xb8, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6];
assert_eq!(
ipv6_to_string(&no_zeros),
Some("2001:db8:1:2:3:4:5:6".to_string())
);
}
#[test]
fn test_ipv6_to_string_compression_in_middle() {
let middle_zeros = [0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
assert_eq!(
ipv6_to_string(&middle_zeros),
Some("2001:db8::1".to_string())
);
}
#[test]
fn test_ipv6_to_string_compression_at_end() {
let end_zeros = [0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
assert_eq!(ipv6_to_string(&end_zeros), Some("2001:db8::".to_string()));
}
#[test]
fn test_ipv6_to_string_compression_at_start() {
let start_zeros = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xc0, 0, 0x02, 0x01,
];
assert_eq!(
ipv6_to_string(&start_zeros),
Some("::ffff:192.0.2.1".to_string())
);
}
#[test]
fn test_ipv6_to_string_multiple_zero_sequences() {
let multiple_zeros = [0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1];
assert_eq!(
ipv6_to_string(&multiple_zeros),
Some("2001:db8::1:0:0:1".to_string())
);
}
#[test]
fn test_ipv6_to_string_single_zero_no_compression() {
let single_zeros = [0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0];
assert_eq!(
ipv6_to_string(&single_zeros),
Some("1:0:1:0:1:0:1:0".to_string())
);
}
#[test]
fn test_ipv6_to_string_leading_zeros_omitted() {
let leading_zeros = [
0x20, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06,
0x00, 0x07,
];
assert_eq!(
ipv6_to_string(&leading_zeros),
Some("2001:1:2:3:4:5:6:7".to_string())
);
}
#[test]
fn test_ipv6_to_string_invalid_length() {
assert_eq!(ipv6_to_string(&[1, 2, 3]), None);
assert_eq!(ipv6_to_string(&[]), None);
assert_eq!(ipv6_to_string(&[0; 15]), None);
assert_eq!(ipv6_to_string(&[0; 17]), None);
}
#[test]
fn test_ipv6_to_string_full_address() {
let full_addr = [0xff; 16];
assert_eq!(
ipv6_to_string(&full_addr),
Some("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff".to_string())
);
}
}