use std::{iter::FromIterator, sync::Arc};
use crate::filters::{self, DynFilterFactory, StaticFilter};
#[cfg(doc)]
use crate::filters::{FilterFactory, FilterRegistry};
pub type FilterMap = std::collections::HashMap<&'static str, Arc<DynFilterFactory>>;
#[derive(Clone)]
pub struct FilterSet(FilterMap);
impl FilterSet {
pub fn default_with(filters: impl IntoIterator<Item = DynFilterFactory>) -> Self {
Self::with(
[
filters::Capture::factory(),
filters::Concatenate::factory(),
filters::Debug::factory(),
filters::Drop::factory(),
filters::Firewall::factory(),
filters::HashedTokenRouter::factory(),
filters::LoadBalancer::factory(),
filters::LocalRateLimit::factory(),
filters::Match::factory(),
filters::Pass::factory(),
filters::Timestamp::factory(),
filters::TokenRouter::factory(),
]
.into_iter()
.chain(filters),
)
}
pub fn with(filters: impl IntoIterator<Item = DynFilterFactory>) -> Self {
Self::from_iter(filters)
}
pub fn get(&self, key: &str) -> Option<&Arc<DynFilterFactory>> {
self.0.get(key)
}
pub fn insert(&mut self, value: DynFilterFactory) -> Option<Arc<DynFilterFactory>> {
self.0.insert(value.name(), Arc::new(value))
}
pub fn iter(&self) -> Iter<'_> {
Iter {
inner: self.0.iter(),
}
}
}
impl Default for FilterSet {
fn default() -> Self {
Self::default_with(Option::into_iter(None))
}
}
impl<I: Iterator<Item = DynFilterFactory>> From<I> for FilterSet {
fn from(iter: I) -> Self {
Self::with(iter)
}
}
impl From<FilterSet> for FilterMap {
fn from(set: FilterSet) -> Self {
set.0
}
}
impl FromIterator<DynFilterFactory> for FilterSet {
fn from_iter<I: IntoIterator<Item = DynFilterFactory>>(iter: I) -> Self {
let mut set = Self(Default::default());
for factory in iter {
set.0.insert(factory.name(), Arc::new(factory));
}
set
}
}
impl IntoIterator for FilterSet {
type IntoIter = IntoIter;
type Item = Arc<DynFilterFactory>;
fn into_iter(self) -> Self::IntoIter {
IntoIter {
inner: self.0.into_iter(),
}
}
}
pub struct IntoIter {
inner: std::collections::hash_map::IntoIter<&'static str, Arc<DynFilterFactory>>,
}
impl Iterator for IntoIter {
type Item = Arc<DynFilterFactory>;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(_, v)| v)
}
}
pub struct Iter<'r> {
inner: std::collections::hash_map::Iter<'r, &'static str, Arc<DynFilterFactory>>,
}
impl<'r> Iterator for Iter<'r> {
type Item = &'r Arc<DynFilterFactory>;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next().map(|(_, v)| v)
}
}