use std::sync::{Arc, RwLock};
use super::FilterPolicy;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum FilterStoreError {
#[error("filter policy lock poisoned")]
Poisoned,
}
#[derive(Clone)]
pub struct FilterStore(Arc<RwLock<FilterPolicy>>);
impl FilterStore {
#[must_use]
pub fn new(policy: FilterPolicy) -> Self {
Self(Arc::new(RwLock::new(policy)))
}
#[must_use]
pub fn default_allow_all() -> Self {
Self::new(FilterPolicy::default())
}
pub fn replace(&self, policy: FilterPolicy) -> Result<(), FilterStoreError> {
self.0
.write()
.map_err(|_| FilterStoreError::Poisoned)
.map(|mut guard| *guard = policy)
}
#[must_use]
pub fn snapshot(&self) -> FilterPolicy {
self.0.read().map(|g| g.clone()).unwrap_or_default()
}
pub fn read<R>(&self, f: impl FnOnce(&FilterPolicy) -> R) -> R {
let guard = self.0.read().expect("filter lock poisoned");
f(&guard)
}
}
impl Default for FilterStore {
fn default() -> Self {
Self::default_allow_all()
}
}