automapper_validation/eval/
evaluator.rs1use super::context::EvaluationContext;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10pub enum ConditionResult {
11 True,
13 False,
15 Unknown,
17}
18
19impl ConditionResult {
20 pub fn is_true(self) -> bool {
22 matches!(self, ConditionResult::True)
23 }
24
25 pub fn is_false(self) -> bool {
27 matches!(self, ConditionResult::False)
28 }
29
30 pub fn is_unknown(self) -> bool {
32 matches!(self, ConditionResult::Unknown)
33 }
34
35 pub fn to_option(self) -> Option<bool> {
37 match self {
38 ConditionResult::True => Some(true),
39 ConditionResult::False => Some(false),
40 ConditionResult::Unknown => None,
41 }
42 }
43}
44
45impl From<bool> for ConditionResult {
46 fn from(value: bool) -> Self {
47 if value {
48 ConditionResult::True
49 } else {
50 ConditionResult::False
51 }
52 }
53}
54
55impl std::fmt::Display for ConditionResult {
56 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57 match self {
58 ConditionResult::True => write!(f, "True"),
59 ConditionResult::False => write!(f, "False"),
60 ConditionResult::Unknown => write!(f, "Unknown"),
61 }
62 }
63}
64
65pub trait ConditionEvaluator: Send + Sync {
71 fn evaluate(&self, condition: u32, ctx: &EvaluationContext) -> ConditionResult;
76
77 fn is_external(&self, condition: u32) -> bool;
80
81 fn is_known(&self, _condition: u32) -> bool {
89 false
90 }
91
92 fn message_type(&self) -> &str;
94
95 fn format_version(&self) -> &str;
97}
98
99impl<T: ConditionEvaluator + ?Sized> ConditionEvaluator for std::sync::Arc<T> {
100 fn evaluate(&self, condition: u32, ctx: &EvaluationContext) -> ConditionResult {
101 (**self).evaluate(condition, ctx)
102 }
103
104 fn is_external(&self, condition: u32) -> bool {
105 (**self).is_external(condition)
106 }
107
108 fn is_known(&self, condition: u32) -> bool {
109 (**self).is_known(condition)
110 }
111
112 fn message_type(&self) -> &str {
113 (**self).message_type()
114 }
115
116 fn format_version(&self) -> &str {
117 (**self).format_version()
118 }
119}
120
121pub trait ExternalConditionProvider: Send + Sync {
131 fn evaluate(&self, condition_name: &str) -> ConditionResult;
137}
138
139pub struct NoOpExternalProvider;
144
145impl ExternalConditionProvider for NoOpExternalProvider {
146 fn evaluate(&self, _condition_name: &str) -> ConditionResult {
147 ConditionResult::Unknown
148 }
149}
150
151#[cfg(test)]
152mod tests {
153 use super::*;
154
155 #[test]
156 fn test_condition_result_is_methods() {
157 assert!(ConditionResult::True.is_true());
158 assert!(!ConditionResult::True.is_false());
159 assert!(!ConditionResult::True.is_unknown());
160
161 assert!(!ConditionResult::False.is_true());
162 assert!(ConditionResult::False.is_false());
163
164 assert!(ConditionResult::Unknown.is_unknown());
165 }
166
167 #[test]
168 fn test_condition_result_to_option() {
169 assert_eq!(ConditionResult::True.to_option(), Some(true));
170 assert_eq!(ConditionResult::False.to_option(), Some(false));
171 assert_eq!(ConditionResult::Unknown.to_option(), None);
172 }
173
174 #[test]
175 fn test_condition_result_from_bool() {
176 assert_eq!(ConditionResult::from(true), ConditionResult::True);
177 assert_eq!(ConditionResult::from(false), ConditionResult::False);
178 }
179
180 #[test]
181 fn test_condition_result_display() {
182 assert_eq!(format!("{}", ConditionResult::True), "True");
183 assert_eq!(format!("{}", ConditionResult::False), "False");
184 assert_eq!(format!("{}", ConditionResult::Unknown), "Unknown");
185 }
186
187 #[test]
188 fn test_noop_external_provider() {
189 let provider = NoOpExternalProvider;
190 assert_eq!(
191 provider.evaluate("MessageSplitting"),
192 ConditionResult::Unknown
193 );
194 assert_eq!(provider.evaluate("anything"), ConditionResult::Unknown);
195 }
196}