Эквивалент inet_ntop в Rust - PullRequest
       20

Эквивалент inet_ntop в Rust

1 голос
/ 26 сентября 2019

Существует ли доступный способ преобразования IP-адресов (как v4, так и v6) из двоичной в текстовую форму в Rust (эквивалент inet_ntop)?

Примеры:

  • "3701A8C0" преобразуется в "55.1.168.192",
  • "20010db8000000000000000000000001" преобразуется в "2001:db8::1".

Ответы [ 2 ]

2 голосов
/ 26 сентября 2019

inet_ntop принимает в качестве входа struct in_addr* или struct in6_addr*.Прямой эквивалент этих структур в Rust: Ipv4Addr и Ipv6Addr, оба из которых реализуют черту Display и поэтому могут быть легко отформатированык тексту или распечатано:

let addr = Ipv4Addr::from (0x3701A8C0);
assert_eq!(format!("{}", addr), String::from ("55.1.168.192"));
println!("{}", addr);
1 голос
/ 26 сентября 2019

AFAIK, прямого преобразования нет, но вы можете сделать это с помощью from_str_radix, а затем с помощью преобразования ip из числового типа:

use std::{
    error::Error,
    io,
    net::{IpAddr, Ipv4Addr, Ipv6Addr},
    str::FromStr,
};

fn convert(s: &str) -> io::Result<IpAddr> {
    if let Ok(u) = u32::from_str_radix(s, 16) {
        Ok(Ipv4Addr::from(u).into())
    } else if let Ok(u) = u128::from_str_radix(s, 16) {
        Ok(Ipv6Addr::from(u).into())
    } else {
        Err(io::Error::new(io::ErrorKind::InvalidData, "Invalid input"))
    }
}

fn main() -> Result<(), Box<dyn Error>> {
    let ip = convert("3701A8C0")?;
    assert_eq!(ip, IpAddr::from_str("55.1.168.192")?);

    let ip = convert("20010db8000000000000000000000001")?;
    assert_eq!(ip, IpAddr::from_str("2001:db8::1")?);

    Ok(())
}

Если вы уже знаете, что оноэто, например, и IPV4, это однострочный:

use std::{
    error::Error,
    net::{IpAddr, Ipv4Addr},
    str::FromStr,
};

fn main() -> Result<(), Box<dyn Error>> {
    let ip = u32::from_str_radix("3701A8C0", 16).map(Ipv4Addr::from)?;
    assert_eq!(ip, IpAddr::from_str("55.1.168.192")?);

    Ok(())
}
...