Skip to main content

edifact_mapper/
evaluator_factory.rs

1//! Factory for creating condition evaluators by variant name and format version.
2
3use automapper_validation::{
4    ConditionEvaluator, ConditionExprEvaluator, ConditionResult, EvaluationContext,
5};
6use mig_bo4e::pid_requirements::PidRequirements;
7use mig_bo4e::pid_validation::PidValidationError;
8use serde_json::Value;
9
10/// Run condition-aware validation using a boxed evaluator.
11///
12/// Internally dispatches to a concrete generic call to satisfy `Sized` bounds.
13pub fn validate_with_boxed_evaluator(
14    evaluator: &dyn ConditionEvaluator,
15    json: &Value,
16    requirements: &PidRequirements,
17    pid: &str,
18    segments: &[mig_types::segment::OwnedSegment],
19) -> Vec<PidValidationError> {
20    // We need a Sized type to pass to ConditionExprEvaluator.
21    // Use a newtype wrapper around &dyn ConditionEvaluator.
22    struct EvalRef<'a>(&'a dyn ConditionEvaluator);
23
24    impl ConditionEvaluator for EvalRef<'_> {
25        fn evaluate(&self, condition: u32, ctx: &EvaluationContext) -> ConditionResult {
26            self.0.evaluate(condition, ctx)
27        }
28
29        fn is_external(&self, condition: u32) -> bool {
30            self.0.is_external(condition)
31        }
32
33        fn is_known(&self, condition: u32) -> bool {
34            self.0.is_known(condition)
35        }
36
37        fn message_type(&self) -> &str {
38            self.0.message_type()
39        }
40
41        fn format_version(&self) -> &str {
42            self.0.format_version()
43        }
44    }
45
46    let wrapper = EvalRef(evaluator);
47    let external = automapper_validation::MapExternalProvider::new(Default::default());
48    let ctx = EvaluationContext::new(pid, &external, segments);
49    let expr_eval = ConditionExprEvaluator::new(&wrapper);
50    crate::conditional_validation::validate_with_conditions(json, requirements, &expr_eval, &ctx)
51}
52
53/// Create a condition evaluator for the given variant and format version.
54///
55/// Returns `None` if no evaluator exists for the combination.
56pub fn create_evaluator(variant: &str, fv: &str) -> Option<Box<dyn ConditionEvaluator>> {
57    match (variant, fv) {
58        // FV2504
59        ("UTILMD_Strom", "FV2504") => Some(Box::new(
60            automapper_validation::UtilmdStromConditionEvaluatorFV2504::default(),
61        )),
62        ("UTILMD_Gas", "FV2504") => Some(Box::new(
63            automapper_validation::UtilmdGasConditionEvaluatorFV2504::default(),
64        )),
65        ("MSCONS", "FV2504") => Some(Box::new(
66            automapper_validation::MsconsConditionEvaluatorFV2504::default(),
67        )),
68        ("ORDERS", "FV2504") => Some(Box::new(
69            automapper_validation::OrdersConditionEvaluatorFV2504::default(),
70        )),
71        ("ORDRSP", "FV2504") => Some(Box::new(
72            automapper_validation::OrdrspConditionEvaluatorFV2504::default(),
73        )),
74        ("INVOIC", "FV2504") => Some(Box::new(
75            automapper_validation::InvoicConditionEvaluatorFV2504::default(),
76        )),
77        ("IFTSTA", "FV2504") => Some(Box::new(
78            automapper_validation::IftstaConditionEvaluatorFV2504::default(),
79        )),
80        ("REMADV", "FV2504") => Some(Box::new(
81            automapper_validation::RemadvConditionEvaluatorFV2504::default(),
82        )),
83        ("COMDIS", "FV2504") => Some(Box::new(
84            automapper_validation::ComdisConditionEvaluatorFV2504::default(),
85        )),
86        ("ORDCHG", "FV2504") => Some(Box::new(
87            automapper_validation::OrdchgConditionEvaluatorFV2504::default(),
88        )),
89        ("PRICAT", "FV2504") => Some(Box::new(
90            automapper_validation::PricatConditionEvaluatorFV2504::default(),
91        )),
92        ("UTILTS", "FV2504") => Some(Box::new(
93            automapper_validation::UtiltsConditionEvaluatorFV2504::default(),
94        )),
95        ("PARTIN", "FV2504") => Some(Box::new(
96            automapper_validation::PartinConditionEvaluatorFV2504::default(),
97        )),
98        ("APERAK", "FV2504") => Some(Box::new(
99            automapper_validation::AperakConditionEvaluatorFV2504::default(),
100        )),
101        ("CONTRL", "FV2504") => Some(Box::new(
102            automapper_validation::ContrlConditionEvaluatorFV2504::default(),
103        )),
104        ("REQOTE", "FV2504") => Some(Box::new(
105            automapper_validation::ReqoteConditionEvaluatorFV2504::default(),
106        )),
107        ("QUOTES", "FV2504") => Some(Box::new(
108            automapper_validation::QuotesConditionEvaluatorFV2504::default(),
109        )),
110        // FV2510
111        ("UTILMD_Strom", "FV2510") => Some(Box::new(
112            automapper_validation::UtilmdStromConditionEvaluatorFV2510::default(),
113        )),
114        ("UTILMD_Gas", "FV2510") => Some(Box::new(
115            automapper_validation::UtilmdGasConditionEvaluatorFV2510::default(),
116        )),
117        ("MSCONS", "FV2510") => Some(Box::new(
118            automapper_validation::MsconsConditionEvaluatorFV2510::default(),
119        )),
120        ("ORDERS", "FV2510") => Some(Box::new(
121            automapper_validation::OrdersConditionEvaluatorFV2510::default(),
122        )),
123        ("ORDRSP", "FV2510") => Some(Box::new(
124            automapper_validation::OrdrspConditionEvaluatorFV2510::default(),
125        )),
126        ("INVOIC", "FV2510") => Some(Box::new(
127            automapper_validation::InvoicConditionEvaluatorFV2510::default(),
128        )),
129        ("IFTSTA", "FV2510") => Some(Box::new(
130            automapper_validation::IftstaConditionEvaluatorFV2510::default(),
131        )),
132        ("REMADV", "FV2510") => Some(Box::new(
133            automapper_validation::RemadvConditionEvaluatorFV2510::default(),
134        )),
135        ("COMDIS", "FV2510") => Some(Box::new(
136            automapper_validation::ComdisConditionEvaluatorFV2510::default(),
137        )),
138        ("ORDCHG", "FV2510") => Some(Box::new(
139            automapper_validation::OrdchgConditionEvaluatorFV2510::default(),
140        )),
141        ("PRICAT", "FV2510") => Some(Box::new(
142            automapper_validation::PricatConditionEvaluatorFV2510::default(),
143        )),
144        ("UTILTS", "FV2510") => Some(Box::new(
145            automapper_validation::UtiltsConditionEvaluatorFV2510::default(),
146        )),
147        ("PARTIN", "FV2510") => Some(Box::new(
148            automapper_validation::PartinConditionEvaluatorFV2510::default(),
149        )),
150        ("APERAK", "FV2510") => Some(Box::new(
151            automapper_validation::AperakConditionEvaluatorFV2510::default(),
152        )),
153        ("CONTRL", "FV2510") => Some(Box::new(
154            automapper_validation::ContrlConditionEvaluatorFV2510::default(),
155        )),
156        ("INSRPT", "FV2510") => Some(Box::new(
157            automapper_validation::InsrptConditionEvaluatorFV2510::default(),
158        )),
159        ("REQOTE", "FV2510") => Some(Box::new(
160            automapper_validation::ReqoteConditionEvaluatorFV2510::default(),
161        )),
162        ("QUOTES", "FV2510") => Some(Box::new(
163            automapper_validation::QuotesConditionEvaluatorFV2510::default(),
164        )),
165        // FV2604
166        ("UTILMD_Strom", "FV2604") => Some(Box::new(
167            automapper_validation::UtilmdStromConditionEvaluatorFV2604::default(),
168        )),
169        ("UTILMD_Gas", "FV2604") => Some(Box::new(
170            automapper_validation::UtilmdGasConditionEvaluatorFV2604::default(),
171        )),
172        ("MSCONS", "FV2604") => Some(Box::new(
173            automapper_validation::MsconsConditionEvaluatorFV2604::default(),
174        )),
175        ("ORDERS", "FV2604") => Some(Box::new(
176            automapper_validation::OrdersConditionEvaluatorFV2604::default(),
177        )),
178        ("ORDRSP", "FV2604") => Some(Box::new(
179            automapper_validation::OrdrspConditionEvaluatorFV2604::default(),
180        )),
181        ("INVOIC", "FV2604") => Some(Box::new(
182            automapper_validation::InvoicConditionEvaluatorFV2604::default(),
183        )),
184        ("IFTSTA", "FV2604") => Some(Box::new(
185            automapper_validation::IftstaConditionEvaluatorFV2604::default(),
186        )),
187        ("REMADV", "FV2604") => Some(Box::new(
188            automapper_validation::RemadvConditionEvaluatorFV2604::default(),
189        )),
190        ("COMDIS", "FV2604") => Some(Box::new(
191            automapper_validation::ComdisConditionEvaluatorFV2604::default(),
192        )),
193        ("ORDCHG", "FV2604") => Some(Box::new(
194            automapper_validation::OrdchgConditionEvaluatorFV2604::default(),
195        )),
196        ("PRICAT", "FV2604") => Some(Box::new(
197            automapper_validation::PricatConditionEvaluatorFV2604::default(),
198        )),
199        ("UTILTS", "FV2604") => Some(Box::new(
200            automapper_validation::UtiltsConditionEvaluatorFV2604::default(),
201        )),
202        ("PARTIN", "FV2604") => Some(Box::new(
203            automapper_validation::PartinConditionEvaluatorFV2604::default(),
204        )),
205        ("APERAK", "FV2604") => Some(Box::new(
206            automapper_validation::AperakConditionEvaluatorFV2604::default(),
207        )),
208        ("CONTRL", "FV2604") => Some(Box::new(
209            automapper_validation::ContrlConditionEvaluatorFV2604::default(),
210        )),
211        ("INSRPT", "FV2604") => Some(Box::new(
212            automapper_validation::InsrptConditionEvaluatorFV2604::default(),
213        )),
214        ("REQOTE", "FV2604") => Some(Box::new(
215            automapper_validation::ReqoteConditionEvaluatorFV2604::default(),
216        )),
217        ("QUOTES", "FV2604") => Some(Box::new(
218            automapper_validation::QuotesConditionEvaluatorFV2604::default(),
219        )),
220        _ => None,
221    }
222}
223
224#[cfg(test)]
225mod tests {
226    use super::*;
227
228    #[test]
229    fn test_known_evaluators_exist() {
230        assert!(create_evaluator("UTILMD_Strom", "FV2504").is_some());
231        assert!(create_evaluator("MSCONS", "FV2504").is_some());
232        assert!(create_evaluator("ORDERS", "FV2510").is_some());
233        assert!(create_evaluator("UTILMD_Gas", "FV2604").is_some());
234    }
235
236    #[test]
237    fn test_unknown_evaluator_returns_none() {
238        assert!(create_evaluator("NONEXISTENT", "FV2504").is_none());
239        assert!(create_evaluator("UTILMD_Strom", "FV9999").is_none());
240    }
241}