psocks/src/list.rs
2026-03-22 03:24:02 +02:00

56 lines
1.6 KiB
Rust

use anyhow::Result;
use log::*;
use std::collections::HashSet;
#[derive(PartialEq, Eq, Hash)]
pub enum Item {
Ending(String),
Exact(String),
}
pub enum List {
Allow(HashSet<Item>),
}
impl List {
pub async fn from_opt(list: &Vec<String>) -> Result<Self> {
let mut this = HashSet::new();
for i in list {
for line in if i.contains("://") {
reqwest::get(i).await?.text().await?
} else {
std::fs::read_to_string(i)?
}
.lines()
{
if line.starts_with("/") || line.starts_with("#") || line.is_empty() {
continue;
}
if !this.insert(if let Some(item) = line.strip_prefix(".") {
debug!("Add `{line}` to the whitelist");
Item::Ending(item.to_string())
} else {
debug!("Add `{line}` exact match to the whitelist");
Item::Exact(line.to_string())
}) {
warn!("Duplicated whitelist record: `{line}`")
}
}
}
info!("Total whitelist entries parsed: {}", this.len());
Ok(Self::Allow(this))
}
pub fn has(&self, value: &str) -> bool {
match self {
Self::Allow(list) => list.iter().any(|item| match item {
Item::Exact(s) => s == value,
Item::Ending(s) => value.ends_with(s),
}),
}
}
pub fn entries(&self) -> usize {
match self {
Self::Allow(list) => list.len(),
}
}
}