psocks/src/rules/list.rs
2026-03-28 06:40:01 +02:00

60 lines
1.7 KiB
Rust

mod rule;
mod source;
use anyhow::Result;
use log::{debug, warn};
use rule::Rule;
use source::Source;
use std::collections::HashSet;
pub struct List {
pub is_enabled: bool,
pub rules: HashSet<Rule>,
pub source: Source,
}
impl List {
pub async fn init(src: &str, is_enabled: bool) -> Result<Self> {
let source = Source::from_str(src)?;
let mut rules = HashSet::new();
load(&mut rules, &source).await?;
Ok(Self {
rules,
source,
is_enabled,
})
}
/// Change rule set status
pub async fn set_enabled(&mut self, is_enabled: bool) -> Result<bool> {
let was_enabled = self.is_enabled;
self.is_enabled = is_enabled;
if self.is_enabled {
debug!("List `{}` enabled", &self.source);
} else {
debug!("List `{}` disabled", &self.source);
}
Ok(was_enabled)
}
/// Reload rule set from it source
pub async fn reload(&mut self) -> Result<()> {
self.rules.clear();
load(&mut self.rules, &self.source).await?;
Ok(())
}
/// Check if rule is exist in the index
pub fn contains(&self, value: &str) -> bool {
self.is_enabled && self.rules.iter().any(|rule| rule.contains(value))
}
}
async fn load(rules: &mut HashSet<Rule>, source: &Source) -> Result<()> {
debug!("Load list `{source}`...");
for line in source.get().await?.lines() {
if line.starts_with("/") || line.starts_with("#") || line.is_empty() {
continue; // skip comments
}
if !rules.insert(Rule::from_line(line)) {
warn!("List `{source}` contains duplicated entry: `{line}`")
}
}
Ok(())
}