Files
reminder-bot/src/web/ip_blocking.rs
T
jude 16786fdc9e Clean up code
Clean up warnings on newer Rust versions. Drop some no-longer used
tables and columns
2026-05-16 18:20:00 +01:00

59 lines
1.7 KiB
Rust

use std::net::Ipv4Addr;
struct IpBlocking {
upper_ips: Vec<u32>,
lower_ips: Vec<u32>,
}
type E = Box<dyn std::error::Error>;
impl IpBlocking {
fn from_path(path: &str) -> Result<Self, E> {
let mut upper_ips: Vec<u32> = vec![];
let mut lower_ips: Vec<u32> = vec![];
let mut reader = csv::Reader::from_path(path)?;
for record in reader.records() {
let record = record?;
let ip_range: Option<(u32, u32)> =
record.get(0).map(|ip| ip.parse::<Ipv4Addr>().ok()).flatten().and_then(
|ip_start| {
record
.get(1)
.map(|ip| ip.parse::<Ipv4Addr>().ok())
.flatten()
.map(|ip_end| (ip_start.into(), ip_end.into()))
},
);
if let Some((ip_start, ip_end)) = ip_range {
upper_ips.push(ip_end);
lower_ips.push(ip_start);
}
}
// Should already be sorted but just in case
upper_ips.sort_unstable();
lower_ips.sort_unstable();
Ok(Self { upper_ips, lower_ips })
}
fn contains<I: Into<u32>>(&self, ip: I) -> bool {
let ip: u32 = ip.into();
let _prev_index = self.upper_ips.len() - 1;
let mut index = self.upper_ips.len() / 2;
loop {
if self.upper_ips[index] <= ip && self.lower_ips[index] >= ip {
return true;
}
let diff = self.upper_ips.len() - index;
if self.upper_ips[index] < ip {
index += diff / 2;
}
}
}
}