1use crate::{
4 condition::{Condition, ConditionMode, ConditionOperator, ConditionSelector},
5 matchable::Matchable,
6 matchers::RuleMatcher,
7};
8use std::any::Any;
9
10pub struct MatcherBuilder<'a, T: Matchable> {
29 mode: ConditionMode,
30 conditions: Vec<Condition<'a, T>>,
31}
32
33impl<'a, T: Matchable + 'static> MatcherBuilder<'a, T> {
34 pub fn new() -> Self {
36 Self {
37 mode: ConditionMode::AND,
38 conditions: Vec::new(),
39 }
40 }
41
42 pub fn mode(mut self, mode: ConditionMode) -> Self {
44 self.mode = mode;
45 self
46 }
47
48 pub fn value_equals(mut self, expected: T) -> Self {
50 self.conditions.push(Condition {
51 selector: ConditionSelector::Value(expected),
52 operator: ConditionOperator::Equals,
53 });
54 self
55 }
56
57 pub fn value_not_equals(mut self, expected: T) -> Self {
59 self.conditions.push(Condition {
60 selector: ConditionSelector::Value(expected),
61 operator: ConditionOperator::NotEquals,
62 });
63 self
64 }
65
66 pub fn length(mut self, len: usize, operator: ConditionOperator) -> Self {
68 self.conditions.push(Condition {
69 selector: ConditionSelector::Length(len),
70 operator,
71 });
72 self
73 }
74
75 pub fn length_equals(self, len: usize) -> Self {
77 self.length(len, ConditionOperator::Equals)
78 }
79
80 pub fn length_gte(self, len: usize) -> Self {
82 self.length(len, ConditionOperator::GreaterThanOrEqual)
83 }
84
85 pub fn length_lte(self, len: usize) -> Self {
87 self.length(len, ConditionOperator::LessThanOrEqual)
88 }
89
90 pub fn condition(mut self, condition: Condition<'a, T>) -> Self {
92 self.conditions.push(condition);
93 self
94 }
95
96 pub fn build(self) -> RuleMatcher<'a, T> {
98 RuleMatcher {
99 mode: self.mode,
100 conditions: self.conditions,
101 }
102 }
103}
104
105impl<'a, T: Matchable + 'static> Default for MatcherBuilder<'a, T> {
106 fn default() -> Self {
107 Self::new()
108 }
109}
110
111pub struct FieldConditionBuilder<'a, T> {
132 field: &'a str,
133 _phantom: std::marker::PhantomData<T>,
134}
135
136impl<'a, T: Matchable> FieldConditionBuilder<'a, T> {
137 pub fn new(field: &'a str) -> Self {
139 Self {
140 field,
141 _phantom: std::marker::PhantomData,
142 }
143 }
144
145 pub fn equals(self, value: &'a dyn Any) -> Condition<'a, T> {
147 Condition {
148 selector: ConditionSelector::FieldValue(self.field, value),
149 operator: ConditionOperator::Equals,
150 }
151 }
152
153 pub fn not_equals(self, value: &'a dyn Any) -> Condition<'a, T> {
155 Condition {
156 selector: ConditionSelector::FieldValue(self.field, value),
157 operator: ConditionOperator::NotEquals,
158 }
159 }
160
161 pub fn gt(self, value: &'a dyn Any) -> Condition<'a, T> {
163 Condition {
164 selector: ConditionSelector::FieldValue(self.field, value),
165 operator: ConditionOperator::GreaterThan,
166 }
167 }
168
169 pub fn gte(self, value: &'a dyn Any) -> Condition<'a, T> {
171 Condition {
172 selector: ConditionSelector::FieldValue(self.field, value),
173 operator: ConditionOperator::GreaterThanOrEqual,
174 }
175 }
176
177 pub fn lt(self, value: &'a dyn Any) -> Condition<'a, T> {
179 Condition {
180 selector: ConditionSelector::FieldValue(self.field, value),
181 operator: ConditionOperator::LessThan,
182 }
183 }
184
185 pub fn lte(self, value: &'a dyn Any) -> Condition<'a, T> {
187 Condition {
188 selector: ConditionSelector::FieldValue(self.field, value),
189 operator: ConditionOperator::LessThanOrEqual,
190 }
191 }
192
193 pub fn contains(self, value: &'a dyn Any) -> Condition<'a, T> {
195 Condition {
196 selector: ConditionSelector::FieldValue(self.field, value),
197 operator: ConditionOperator::Contains,
198 }
199 }
200
201 pub fn starts_with(self, value: &'a dyn Any) -> Condition<'a, T> {
203 Condition {
204 selector: ConditionSelector::FieldValue(self.field, value),
205 operator: ConditionOperator::StartsWith,
206 }
207 }
208
209 pub fn ends_with(self, value: &'a dyn Any) -> Condition<'a, T> {
211 Condition {
212 selector: ConditionSelector::FieldValue(self.field, value),
213 operator: ConditionOperator::EndsWith,
214 }
215 }
216}
217
218pub fn field<'a, T: Matchable>(name: &'a str) -> FieldConditionBuilder<'a, T> {
220 FieldConditionBuilder::new(name)
221}