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