use std::net::Ipv4Addr; struct IpBlocking { upper_ips: Vec, lower_ips: Vec, } type E = Box; impl IpBlocking { fn from_path(path: &str) -> Result { let mut upper_ips: Vec = vec![]; let mut lower_ips: Vec = 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::().ok()).flatten().and_then( |ip_start| { record .get(1) .map(|ip| ip.parse::().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>(&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; } } } }