1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
use crate::{Ops, Port, Range}; use std::str::FromStr; use std::{net::Ipv4Addr, net::TcpListener}; pub struct TcpPort; impl Ops for TcpPort { fn any(host: &str) -> Option<Port> { let r = Range::default(); (r.min..=r.max) .filter(|&p| TcpPort::is_port_available(host, p)) .nth(0) } fn in_range(host: &str, r: Range) -> Option<Port> { (r.min..=r.max) .filter(|&p| TcpPort::is_port_available(host, p)) .nth(0) } fn from_list(host: &str, v: Vec<Port>) -> Option<Port> { v.into_iter() .filter(|&p| TcpPort::is_port_available(host, p)) .nth(0) } fn except(host: &str, v: Vec<Port>) -> Option<Port> { let r = Range::default(); (r.min..=r.max) .filter(|&p| !v.contains(&p) && TcpPort::is_port_available(host, p)) .nth(0) } fn in_range_except(host: &str, r: Range, v: Vec<Port>) -> Option<Port> { (r.min..=r.max) .filter(|&p| !v.contains(&p) && TcpPort::is_port_available(host, p)) .nth(0) } fn is_port_available(host: &str, p: Port) -> bool { matches!( TcpListener::bind((Ipv4Addr::from_str(host).unwrap(), p)).is_ok(), true ) } }