use ipaddress::IPAddress;
use num_integer::Integer;
use num_traits::cast::ToPrimitive;
use core::ops::Shr;
use num::bigint::BigUint;
use num_traits::Zero;
pub fn new<S: Into<String>>(_str: S) -> Result<IPAddress, String> {
let str = _str.into();
let (ip, o_netmask) = IPAddress::split_at_slash(&str);
let split_colon = ip.split(":").collect::<Vec<&str>>();
if split_colon.len() <= 1 {
return Err(format!("not mapped format-1: {}", &str));
}
let mut netmask = String::from("");
if o_netmask.is_some() {
netmask = format!("/{}", o_netmask.unwrap());
}
let ipv4_str = String::from(*split_colon.iter().last().unwrap());
if IPAddress::is_valid_ipv4(ipv4_str.clone()) {
let ipv4 = IPAddress::parse(format!("{}{}", ipv4_str, netmask));
if ipv4.is_err() {
println!("---2");
return ipv4;
}
let addr = ipv4.unwrap();
let ipv6_bits = ::ip_bits::v6();
let ref part_mod = ipv6_bits.part_mod;
let up_addr = addr.host_address.clone();
let down_addr = addr.host_address.clone();
let mut rebuild_ipv6 = String::new();
let mut colon = "";
for i in 0..split_colon.len()-1 {
rebuild_ipv6.push_str(colon);
rebuild_ipv6.push_str(split_colon[i]);
colon = ":";
}
rebuild_ipv6.push_str(colon);
let rebuild_ipv4 = format!("{:x}:{:x}/{}",
up_addr.shr(::ip_bits::v6().part_bits).mod_floor(&part_mod).to_u16().unwrap(),
down_addr.mod_floor(&part_mod).to_u16().unwrap(),
ipv6_bits.bits-addr.prefix.host_prefix());
rebuild_ipv6.push_str(&rebuild_ipv4);
let r_ipv6 = IPAddress::parse(rebuild_ipv6.clone());
if r_ipv6.is_err() {
println!("---3|{}", &rebuild_ipv6);
return r_ipv6;
}
if r_ipv6.clone().unwrap().is_mapped() {
return r_ipv6;
}
let ipv6 = r_ipv6.unwrap();
let p96bit = ipv6.host_address.clone().shr(32);
if p96bit != BigUint::zero() {
println!("---4|{}", &rebuild_ipv6);
return Err(format!("is not a mapped address:{}", rebuild_ipv6));
}
{
let r_ipv6 = IPAddress::parse(format!("::ffff:{}", rebuild_ipv4));
if r_ipv6.is_err() {
println!("---3|{}", &rebuild_ipv6);
return r_ipv6;
}
return r_ipv6;
}
}
return Err(format!("unknown mapped format:{}", str));
}