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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use cidr_utils::cidr::{IpCidr, Ipv4Cidr};
use std::fmt::Formatter;
use std::net::Ipv4Addr;
use thiserror::Error;
pub mod tcp;
#[derive(Clone, Debug, Eq, Hash)]
pub struct ConnectionId(pub String);
impl std::fmt::Display for ConnectionId {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl PartialEq<Self> for ConnectionId {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
#[derive(Debug, PartialEq)]
pub enum IpAddress {
Exact(Ipv4Addr),
Cidr(Ipv4Cidr),
}
#[derive(Error, Debug)]
pub enum IpAddressParseError {
#[error("The value '{0}' was not a valid ip address or cidr value")]
InvalidValue(String),
}
impl IpAddress {
pub fn matches(&self, other_address: &Ipv4Addr) -> bool {
match self {
IpAddress::Exact(self_address) => self_address == other_address,
IpAddress::Cidr(cidr) => cidr.contains(other_address),
}
}
pub fn parse_comma_delimited_list(
input: Option<&String>,
) -> Result<Vec<IpAddress>, IpAddressParseError> {
let mut ips = Vec::new();
match input {
None => (),
Some(input) => {
for input in input.split(",") {
let ip = if let Ok(ip) = input.parse::<Ipv4Addr>() {
Some(IpAddress::Exact(ip))
} else if let Ok(cidr) = IpCidr::from_str(input) {
match cidr {
IpCidr::V4(cidr) => Some(IpAddress::Cidr(cidr)),
_ => None,
}
} else {
None
};
if let Some(ip) = ip {
ips.push(ip);
} else {
return Err(IpAddressParseError::InvalidValue(input.to_string()));
}
}
}
}
Ok(ips)
}
}