use std::{fmt, hash};
use crate::{error::MatcherError, event::Event, predicate::ElementaryPredicate};
pub trait SubscriptionKey: fmt::Debug + Clone + PartialEq + Eq + hash::Hash {}
impl<T> SubscriptionKey for T where T: fmt::Debug + Clone + PartialEq + Eq + hash::Hash {}
#[derive(Debug, Clone, PartialEq)]
pub struct Subscription<T: SubscriptionKey> {
pub id: T,
pub predicates: Vec<ElementaryPredicate>,
}
impl<T: SubscriptionKey> Subscription<T> {
pub fn new(id: T) -> Self {
Self {
id,
predicates: Vec::new(),
}
}
pub fn with_predicate(mut self, predicate: ElementaryPredicate) -> Self {
self.predicates.push(predicate);
self
}
pub fn with_predicates(mut self, predicates: Vec<ElementaryPredicate>) -> Self {
self.predicates.extend(predicates);
self
}
pub fn matches(&self, event: &impl Event) -> Result<bool, MatcherError> {
for predicate in &self.predicates {
if !predicate.evaluate(event)? {
return Ok(false);
}
}
Ok(true)
}
}
impl<T: SubscriptionKey> fmt::Display for Subscription<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Subscription(id={:?}, predicates=[", self.id)?;
for (i, predicate) in self.predicates.iter().enumerate() {
if i > 0 {
write!(f, " AND ")?;
}
write!(f, "{predicate}")?;
}
write!(f, "])")
}
}