get_port/
tcp.rs

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