implement session cache

This commit is contained in:
postscriptum 2026-03-22 12:30:09 +02:00
parent e5268e49f1
commit 8de35ff3a6
5 changed files with 123 additions and 31 deletions

68
src/list/cache.rs Normal file
View file

@ -0,0 +1,68 @@
use anyhow::{Result, bail};
use std::{collections::HashSet, path::PathBuf};
use tokio::fs;
pub struct Cache(Option<PathBuf>);
impl Cache {
pub async fn from_path(path: Option<PathBuf>) -> Result<Self> {
Ok(Self(match path {
Some(p) => {
init_file(&p).await?;
Some(p)
}
None => None,
}))
}
pub async fn read(&self) -> Result<Option<String>> {
Ok(if let Some(ref p) = self.0 {
init_file(p).await?;
Some(fs::read_to_string(p).await?)
} else {
None
})
}
pub async fn allow(&self, rule: &str) -> Result<()> {
if let Some(ref p) = self.0 {
init_file(p).await?;
let mut rules = HashSet::new();
let lines = fs::read_to_string(p).await?;
for line in lines.lines() {
rules.insert(line);
}
rules.insert(rule);
fs::write(p, rules.into_iter().collect::<Vec<_>>().join("\n")).await?;
}
Ok(())
}
pub async fn block(&self, rule: &str) -> Result<()> {
if let Some(ref p) = self.0 {
init_file(p).await?;
let mut rules = HashSet::new();
let lines = fs::read_to_string(p).await?;
for line in lines.lines() {
if line != rule {
rules.insert(line);
}
}
fs::write(p, rules.into_iter().collect::<Vec<_>>().join("\n")).await?;
}
Ok(())
}
}
/// Make sure that cache file is always exist (e.g. user may remove it when the daemon is running)
async fn init_file(path: &PathBuf) -> Result<()> {
if path.exists() {
if path.is_file() {
return Ok(());
} else {
bail!(
"Cache path `{}` exist but it is not a file!",
path.to_string_lossy()
)
}
}
fs::write(path, "").await?;
Ok(())
}