use crate::exchange::Exchange;
use std::sync::Arc;
pub struct FilterPredicate(pub Arc<dyn Fn(&Exchange) -> bool + Send + Sync>);
impl FilterPredicate {
pub fn new<F>(f: F) -> Self
where
F: Fn(&Exchange) -> bool + Send + Sync + 'static,
{
FilterPredicate(Arc::new(f))
}
}
impl Clone for FilterPredicate {
fn clone(&self) -> Self {
FilterPredicate(Arc::clone(&self.0))
}
}
impl std::fmt::Debug for FilterPredicate {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("FilterPredicate(..)")
}
}
impl std::ops::Deref for FilterPredicate {
type Target = dyn Fn(&Exchange) -> bool + Send + Sync;
fn deref(&self) -> &Self::Target {
&*self.0
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{Exchange, Message};
#[test]
fn test_filter_predicate_is_callable() {
let pred = FilterPredicate::new(|ex: &Exchange| ex.input.body.as_text().is_some());
let ex = Exchange::new(Message::new("hello"));
assert!(pred(&ex));
}
#[test]
fn test_filter_predicate_debug_is_redacted() {
let pred = FilterPredicate::new(|_: &Exchange| true);
assert_eq!(format!("{pred:?}"), "FilterPredicate(..)");
}
#[test]
fn test_filter_predicate_clone_shares_arc() {
let pred = FilterPredicate::new(|_: &Exchange| true);
let cloned = pred.clone();
assert!(matches!(cloned, FilterPredicate(_)));
}
}