1
0
mirror of https://github.com/jht5945/rust_util.git synced 2025-12-27 15:40:03 +08:00

feat: add ip address port

This commit is contained in:
2020-09-06 21:58:33 +08:00
parent 90fc790b64
commit 79e2618e98
2 changed files with 77 additions and 11 deletions

View File

@@ -1,6 +1,6 @@
[package]
name = "rust_util"
version = "0.6.6"
version = "0.6.7"
authors = ["Hatter Jiang <jht5945@gmail.com>"]
edition = "2018"
description = "Hatter's Rust Util"

View File

@@ -3,6 +3,8 @@ use std::result::Result;
use std::net::SocketAddr;
use crate::XResult;
const DEFAULT_LISTEN_ADDR: [u8; 4] = [127, 0, 0, 1];
#[derive(Debug, Clone)]
pub enum IpAddress {
Ipv4([u8; 4]),
@@ -86,6 +88,60 @@ impl Display for IpAddressMask {
}
}
#[derive(Debug, Clone)]
pub struct IpAddressAndPort {
pub ip: IpAddress,
pub port: u16,
}
impl IpAddressAndPort {
pub fn parse(ip_address_and_port: &str) -> Option<Self> {
if let Some((ipv4, port)) = parse_ip_and_port(ip_address_and_port) {
return Some(IpAddressAndPort {
ip: IpAddress::Ipv4(ipv4),
port,
});
}
None
}
pub fn to_address(&self) -> String {
format!("{}:{}", self.ip, self.port)
}
pub fn to_ipv4_and_port(&self) -> ([u8; 4], u16) {
match self.ip {
IpAddress::Ipv4(ipv4) => (ipv4, self.port),
}
}
}
impl Display for IpAddressAndPort {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(f, "{}:{}", self.ip, self.port)
}
}
// :8080 -> 127.0.0.1:8080
fn parse_ip_and_port(listen: &str) -> Option<([u8; 4], u16)> {
let listen_addr = match listen.split(':').next() {
None => DEFAULT_LISTEN_ADDR,
Some(addr) if addr.is_empty() => DEFAULT_LISTEN_ADDR,
Some(addr) => match parse_ipv4_addr(addr) {
Some(parsed_ip_address) => parsed_ip_address, None => return None,
},
};
let listen_port = match listen.split(':').nth(1) {
None => return None,
Some(port) => match port.parse::<u16>() {
Ok(port) => port, Err(_) => return None,
},
};
Some((listen_addr, listen_port))
}
fn ipv4_mask(mask: u8) -> u32 {
let mut r = 0_u32;
for _ in 0..mask {
@@ -118,15 +174,25 @@ fn parse_ipv4_addr(addr: &str) -> Option<[u8; 4]> {
}
#[test]
fn test_is_matches() {
fn test_ip_address_is_matches() {
let addr = SocketAddr::new(std::net::IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 1)), 123);
let addr2 = SocketAddr::new(std::net::IpAddr::V4(std::net::Ipv4Addr::new(127, 0, 0, 2)), 123);
assert_eq!(true, IpAddressMask::parse_ipv4("127.0.0.1").unwrap().is_matches(&addr));
assert_eq!(true, IpAddressMask::parse_ipv4("127.0.0.1/32").unwrap().is_matches(&addr));
assert_eq!(true, IpAddressMask::parse_ipv4("127.0.0.1/31").unwrap().is_matches(&addr));
assert_eq!(true, IpAddressMask::parse_ipv4("127.0.0.1/30").unwrap().is_matches(&addr));
assert_eq!(false, IpAddressMask::parse_ipv4("127.0.0.1").unwrap().is_matches(&addr2));
assert_eq!(false, IpAddressMask::parse_ipv4("127.0.0.1/32").unwrap().is_matches(&addr2));
assert_eq!(false, IpAddressMask::parse_ipv4("127.0.0.1/31").unwrap().is_matches(&addr2));
assert_eq!(true, IpAddressMask::parse_ipv4("127.0.0.1/30").unwrap().is_matches(&addr2));
}
assert_eq!(true, IpAddressMask::parse_ipv4("127.0.0.1").unwrap().is_matches(&addr));
assert_eq!(true, IpAddressMask::parse_ipv4("127.0.0.1/32").unwrap().is_matches(&addr));
assert_eq!(true, IpAddressMask::parse_ipv4("127.0.0.1/31").unwrap().is_matches(&addr));
assert_eq!(true, IpAddressMask::parse_ipv4("127.0.0.1/30").unwrap().is_matches(&addr));
assert_eq!(false, IpAddressMask::parse_ipv4("127.0.0.1").unwrap().is_matches(&addr2));
assert_eq!(false, IpAddressMask::parse_ipv4("127.0.0.1/32").unwrap().is_matches(&addr2));
assert_eq!(false, IpAddressMask::parse_ipv4("127.0.0.1/31").unwrap().is_matches(&addr2));
assert_eq!(true, IpAddressMask::parse_ipv4("127.0.0.1/30").unwrap().is_matches(&addr2));
}
#[test]
fn test_ip_address_port() {
let ip_address_and_port = IpAddressAndPort::parse(":80");
assert_eq!("127.0.0.1:80", format!("{}", ip_address_and_port.unwrap()));
let ip_address_and_port = IpAddressAndPort::parse("0.0.0.0:80");
assert_eq!("0.0.0.0:80", format!("{}", ip_address_and_port.unwrap()));
let ip_address_and_port = IpAddressAndPort::parse("1.1.1.1:80");
assert_eq!("1.1.1.1:80", format!("{}", ip_address_and_port.unwrap()));
}