nautalid 0.1.0

Scratch container substrate — TLS 1.3 HTTP/2+3 kernel, LID/AetherDB, optional filter bus (GPL-3.0-or-later).
use std::sync::{Arc, RwLock};

use super::FilterPolicy;
use thiserror::Error;

#[derive(Debug, Error)]
pub enum FilterStoreError {
    #[error("filter policy lock poisoned")]
    Poisoned,
}

/// Shared filter policy (startup env + runtime reload via **`bus`**).
#[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()
    }
}