1use cidr_utils::cidr::{IpCidr, Ipv4Cidr};
4use std::fmt::Formatter;
5use std::net::Ipv4Addr;
6use thiserror::Error;
7
8pub mod tcp;
9
10#[derive(Clone, Debug, Eq, Hash)]
13pub struct ConnectionId(pub String);
14
15impl std::fmt::Display for ConnectionId {
16 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
17 write!(f, "{}", self.0)
18 }
19}
20
21impl PartialEq<Self> for ConnectionId {
22 fn eq(&self, other: &Self) -> bool {
23 self.0 == other.0
24 }
25}
26
27#[derive(Debug, PartialEq)]
29pub enum IpAddress {
30 Exact(Ipv4Addr),
31 Cidr(Ipv4Cidr),
32}
33
34#[derive(Error, Debug)]
36pub enum IpAddressParseError {
37 #[error("The value '{0}' was not a valid ip address or cidr value")]
38 InvalidValue(String),
39}
40
41impl IpAddress {
42 pub fn matches(&self, other_address: &Ipv4Addr) -> bool {
47 match self {
48 IpAddress::Exact(self_address) => self_address == other_address,
49 IpAddress::Cidr(cidr) => cidr.contains(other_address),
50 }
51 }
52
53 pub fn parse_comma_delimited_list(
56 input: Option<&String>,
57 ) -> Result<Vec<IpAddress>, IpAddressParseError> {
58 let mut ips = Vec::new();
59 match input {
60 None => (),
61 Some(input) => {
62 for input in input.split(",") {
63 let ip = if let Ok(ip) = input.parse::<Ipv4Addr>() {
64 Some(IpAddress::Exact(ip))
65 } else if let Ok(cidr) = IpCidr::from_str(input) {
66 match cidr {
67 IpCidr::V4(cidr) => Some(IpAddress::Cidr(cidr)),
68 _ => None,
69 }
70 } else {
71 None
72 };
73
74 if let Some(ip) = ip {
75 ips.push(ip);
76 } else {
77 return Err(IpAddressParseError::InvalidValue(input.to_string()));
78 }
79 }
80 }
81 }
82
83 Ok(ips)
84 }
85}