condition_matcher/
traits.rs

1//! Core traits for the condition-matcher library.
2//!
3//! This module defines the trait hierarchy that enables polymorphic matching:
4//! - [`Matcher`]: Core trait for any type that can match against a value
5//! - [`Evaluate`]: Extended trait for detailed evaluation results
6//! - [`Predicate`]: Trait for individual condition evaluation
7//! - [`MatcherExt`]: Extension trait providing batch operations
8
9use crate::{
10    condition::ConditionMode,
11    matchable::Matchable,
12    result::ConditionResult,
13};
14
15/// Core trait for any type that can match against a value.
16///
17/// This is the primary interface users interact with. Both [`RuleMatcher`](crate::matchers::RuleMatcher)
18/// and [`JsonMatcher`](crate::matchers::JsonMatcher) implement this trait.
19///
20/// # Example
21///
22/// ```rust
23/// use condition_matcher::{Matcher, MatcherBuilder};
24///
25/// let matcher = MatcherBuilder::<i32>::new()
26///     .value_equals(42)
27///     .build();
28///
29/// assert!(matcher.matches(&42));
30/// assert!(!matcher.matches(&41));
31/// ```
32pub trait Matcher<T: Matchable> {
33    /// Check if this matcher matches the given value.
34    fn matches(&self, value: &T) -> bool;
35
36    /// Get the logical combination mode (AND, OR, XOR).
37    fn mode(&self) -> ConditionMode;
38}
39
40/// Extended trait for matchers that provide detailed evaluation results.
41///
42/// Implement this trait when you need to provide detailed information about
43/// why a match succeeded or failed.
44pub trait Evaluate<T: Matchable>: Matcher<T> {
45    /// The result type for detailed evaluation.
46    type Output;
47
48    /// Evaluate with full details (field values, errors, descriptions).
49    fn evaluate(&self, value: &T) -> Self::Output;
50}
51
52/// Trait for individual condition/predicate evaluation.
53///
54/// Implemented by [`Condition`](crate::condition::Condition) to evaluate
55/// a single rule against a value.
56pub trait Predicate<T: Matchable> {
57    /// Test this predicate against a value.
58    fn test(&self, value: &T) -> bool;
59
60    /// Test with detailed result information.
61    fn test_detailed(&self, value: &T) -> ConditionResult;
62}
63
64/// Extension trait providing batch operations.
65///
66/// This trait is blanket implemented for all [`Matcher`] types, providing
67/// convenient methods for operating on collections of values.
68///
69/// # Example
70///
71/// ```rust
72/// use condition_matcher::{Matcher, MatcherExt, MatcherBuilder};
73///
74/// let matcher = MatcherBuilder::<i32>::new()
75///     .value_equals(42)
76///     .build();
77///
78/// let values = vec![40, 41, 42, 43, 42];
79/// let matches = matcher.filter(&values);
80/// assert_eq!(matches.len(), 2);
81/// ```
82pub trait MatcherExt<T: Matchable>: Matcher<T> {
83    /// Filter values, returning references to those that match.
84    fn filter<'a>(&self, values: &'a [T]) -> Vec<&'a T> {
85        values.iter().filter(|v| self.matches(v)).collect()
86    }
87
88    /// Filter values in parallel (requires `parallel` feature).
89    #[cfg(feature = "parallel")]
90    fn filter_par<'a>(&self, values: &'a [T]) -> Vec<&'a T>
91    where
92        T: Sync,
93        Self: Sync,
94    {
95        use rayon::prelude::*;
96        values.par_iter().filter(|v| self.matches(v)).collect()
97    }
98
99    /// Check all values, returning match results as a vector of booleans.
100    fn matches_all(&self, values: &[T]) -> Vec<bool> {
101        values.iter().map(|v| self.matches(v)).collect()
102    }
103
104    /// Check all values in parallel (requires `parallel` feature).
105    #[cfg(feature = "parallel")]
106    fn matches_all_par(&self, values: &[T]) -> Vec<bool>
107    where
108        T: Sync,
109        Self: Sync,
110    {
111        use rayon::prelude::*;
112        values.par_iter().map(|v| self.matches(v)).collect()
113    }
114}
115
116// Blanket implementation - any Matcher gets batch operations for free
117impl<T: Matchable, M: Matcher<T>> MatcherExt<T> for M {}
118
119// Blanket implementation - references to Matchers also implement Matcher
120impl<T: Matchable, M: Matcher<T>> Matcher<T> for &M {
121    fn matches(&self, value: &T) -> bool {
122        (*self).matches(value)
123    }
124
125    fn mode(&self) -> ConditionMode {
126        (*self).mode()
127    }
128}
129