1#![allow(clippy::style, clippy::complexity)]
11
12#[allow(unused_imports)]
13use crate::eval::format_validators::*;
14use crate::eval::{ConditionEvaluator, ConditionResult, EvaluationContext};
15
16pub struct PartinConditionEvaluatorFV2510 {
18 external_conditions: std::collections::HashSet<u32>,
20}
21
22impl Default for PartinConditionEvaluatorFV2510 {
23 fn default() -> Self {
24 let mut external_conditions = std::collections::HashSet::new();
25 external_conditions.insert(1);
26 external_conditions.insert(2);
27 external_conditions.insert(4);
28 external_conditions.insert(5);
29 external_conditions.insert(17);
30 external_conditions.insert(18);
31 external_conditions.insert(19);
32 external_conditions.insert(20);
33 external_conditions.insert(21);
34 external_conditions.insert(22);
35 external_conditions.insert(23);
36 external_conditions.insert(24);
37 external_conditions.insert(25);
38 external_conditions.insert(26);
39 external_conditions.insert(35);
40 external_conditions.insert(36);
41 Self {
42 external_conditions,
43 }
44 }
45}
46
47impl ConditionEvaluator for PartinConditionEvaluatorFV2510 {
48 fn message_type(&self) -> &str {
49 "PARTIN"
50 }
51
52 fn format_version(&self) -> &str {
53 "FV2510"
54 }
55
56 fn evaluate(&self, condition: u32, ctx: &EvaluationContext) -> ConditionResult {
57 match condition {
58 1 => self.evaluate_1(ctx),
59 2 => self.evaluate_2(ctx),
60 3 => self.evaluate_3(ctx),
61 4 => self.evaluate_4(ctx),
62 5 => self.evaluate_5(ctx),
63 6 => self.evaluate_6(ctx),
64 7 => self.evaluate_7(ctx),
65 8 => self.evaluate_8(ctx),
66 10 => self.evaluate_10(ctx),
67 11 => self.evaluate_11(ctx),
68 12 => self.evaluate_12(ctx),
69 13 => self.evaluate_13(ctx),
70 14 => self.evaluate_14(ctx),
71 15 => self.evaluate_15(ctx),
72 16 => self.evaluate_16(ctx),
73 17 => self.evaluate_17(ctx),
74 18 => self.evaluate_18(ctx),
75 19 => self.evaluate_19(ctx),
76 20 => self.evaluate_20(ctx),
77 21 => self.evaluate_21(ctx),
78 22 => self.evaluate_22(ctx),
79 23 => self.evaluate_23(ctx),
80 24 => self.evaluate_24(ctx),
81 25 => self.evaluate_25(ctx),
82 26 => self.evaluate_26(ctx),
83 27 => self.evaluate_27(ctx),
84 28 => self.evaluate_28(ctx),
85 29 => self.evaluate_29(ctx),
86 30 => self.evaluate_30(ctx),
87 31 => self.evaluate_31(ctx),
88 32 => self.evaluate_32(ctx),
89 33 => self.evaluate_33(ctx),
90 34 => self.evaluate_34(ctx),
91 35 => self.evaluate_35(ctx),
92 36 => self.evaluate_36(ctx),
93 490 => self.evaluate_490(ctx),
94 491 => self.evaluate_491(ctx),
95 494 => self.evaluate_494(ctx),
96 500 => self.evaluate_500(ctx),
97 501 => self.evaluate_501(ctx),
98 502 => self.evaluate_502(ctx),
99 503 => self.evaluate_503(ctx),
100 504 => self.evaluate_504(ctx),
101 505 => self.evaluate_505(ctx),
102 506 => self.evaluate_506(ctx),
103 508 => self.evaluate_508(ctx),
104 908 => self.evaluate_908(ctx),
105 931 => self.evaluate_931(ctx),
106 932 => self.evaluate_932(ctx),
107 933 => self.evaluate_933(ctx),
108 939 => self.evaluate_939(ctx),
109 940 => self.evaluate_940(ctx),
110 _ => ConditionResult::Unknown,
111 }
112 }
113
114 fn is_external(&self, condition: u32) -> bool {
115 self.external_conditions.contains(&condition)
116 }
117 fn is_known(&self, condition: u32) -> bool {
118 matches!(
119 condition,
120 1 | 2
121 | 3
122 | 4
123 | 5
124 | 6
125 | 7
126 | 8
127 | 10
128 | 11
129 | 12
130 | 13
131 | 14
132 | 15
133 | 16
134 | 17
135 | 18
136 | 19
137 | 20
138 | 21
139 | 22
140 | 23
141 | 24
142 | 25
143 | 26
144 | 27
145 | 28
146 | 29
147 | 30
148 | 31
149 | 32
150 | 33
151 | 34
152 | 35
153 | 36
154 | 490
155 | 491
156 | 494
157 | 500
158 | 501
159 | 502
160 | 503
161 | 504
162 | 505
163 | 506
164 | 508
165 | 908
166 | 931
167 | 932
168 | 933
169 | 939
170 | 940
171 )
172 }
173}
174
175impl PartinConditionEvaluatorFV2510 {
176 fn evaluate_1(&self, ctx: &EvaluationContext) -> ConditionResult {
179 ctx.external.evaluate("mp_id_is_strom")
180 }
181
182 fn evaluate_2(&self, ctx: &EvaluationContext) -> ConditionResult {
185 ctx.external.evaluate("country_has_postal_code")
186 }
187
188 fn evaluate_4(&self, ctx: &EvaluationContext) -> ConditionResult {
191 ctx.external.evaluate("predecessor_version_exists")
192 }
193
194 fn evaluate_3(&self, _ctx: &EvaluationContext) -> ConditionResult {
196 ConditionResult::True
198 }
199
200 fn evaluate_5(&self, ctx: &EvaluationContext) -> ConditionResult {
203 ctx.external.evaluate("recipient_is_lf")
204 }
205
206 fn evaluate_6(&self, ctx: &EvaluationContext) -> ConditionResult {
208 let coms = ctx.find_segments("COM");
209 if coms.is_empty() {
210 return ConditionResult::Unknown;
211 }
212 ConditionResult::from(coms.iter().any(|s| {
213 s.elements
214 .first()
215 .and_then(|e| e.get(1))
216 .is_some_and(|v| v == "EM")
217 }))
218 }
219
220 fn evaluate_7(&self, ctx: &EvaluationContext) -> ConditionResult {
222 let coms = ctx.find_segments("COM");
223 if coms.is_empty() {
224 return ConditionResult::Unknown;
225 }
226 ConditionResult::from(coms.iter().any(|s| {
227 s.elements
228 .first()
229 .and_then(|e| e.get(1))
230 .is_some_and(|v| matches!(v.as_str(), "TE" | "FX" | "AJ" | "AL"))
231 }))
232 }
233
234 fn evaluate_8(&self, ctx: &EvaluationContext) -> ConditionResult {
236 let coms = ctx.find_segments("COM");
237 if coms.is_empty() {
238 return ConditionResult::Unknown;
239 }
240 ConditionResult::from(coms.iter().any(|s| {
241 s.elements
242 .first()
243 .and_then(|e| e.get(1))
244 .is_some_and(|v| matches!(v.as_str(), "TE" | "FX"))
245 }))
246 }
247
248 fn evaluate_10(&self, ctx: &EvaluationContext) -> ConditionResult {
250 match ctx.find_segment("BGM") {
251 None => ConditionResult::False, Some(bgm) => ConditionResult::from(
253 bgm.elements
254 .get(4)
255 .and_then(|e| e.first())
256 .map(|v| v != "11")
257 .unwrap_or(true),
258 ),
259 }
260 }
261
262 fn evaluate_11(&self, ctx: &EvaluationContext) -> ConditionResult {
264 let nads = ctx.find_segments_with_qualifier("NAD", 0, "SU");
265 match nads.first() {
266 None => ConditionResult::False, Some(nad) => ConditionResult::from(
268 nad.elements
269 .get(8)
270 .and_then(|e| e.first())
271 .is_some_and(|v| v == "DE"),
272 ),
273 }
274 }
275
276 fn evaluate_12(&self, ctx: &EvaluationContext) -> ConditionResult {
278 let nads = ctx.find_segments_with_qualifier("NAD", 0, "DDM");
279 match nads.first() {
280 None => ConditionResult::False, Some(nad) => ConditionResult::from(
282 nad.elements
283 .get(8)
284 .and_then(|e| e.first())
285 .is_some_and(|v| v == "DE"),
286 ),
287 }
288 }
289
290 fn evaluate_13(&self, ctx: &EvaluationContext) -> ConditionResult {
292 let nads = ctx.find_segments_with_qualifier("NAD", 0, "DEB");
293 match nads.first() {
294 None => ConditionResult::False, Some(nad) => ConditionResult::from(
296 nad.elements
297 .get(8)
298 .and_then(|e| e.first())
299 .is_some_and(|v| v == "DE"),
300 ),
301 }
302 }
303
304 fn evaluate_14(&self, ctx: &EvaluationContext) -> ConditionResult {
306 let nads = ctx.find_segments_with_qualifier("NAD", 0, "SU");
307 match nads.first() {
308 None => ConditionResult::False, Some(nad) => ConditionResult::from(
310 nad.elements
311 .get(8)
312 .and_then(|e| e.first())
313 .map(|v| v != "DE")
314 .unwrap_or(true),
315 ),
316 }
317 }
318
319 fn evaluate_15(&self, ctx: &EvaluationContext) -> ConditionResult {
321 let nads = ctx.find_segments_with_qualifier("NAD", 0, "DDM");
322 match nads.first() {
323 None => ConditionResult::False, Some(nad) => ConditionResult::from(
325 nad.elements
326 .get(8)
327 .and_then(|e| e.first())
328 .map(|v| v != "DE")
329 .unwrap_or(true),
330 ),
331 }
332 }
333
334 fn evaluate_16(&self, ctx: &EvaluationContext) -> ConditionResult {
336 let nads = ctx.find_segments_with_qualifier("NAD", 0, "DEB");
337 match nads.first() {
338 None => ConditionResult::False, Some(nad) => ConditionResult::from(
340 nad.elements
341 .get(8)
342 .and_then(|e| e.first())
343 .map(|v| v != "DE")
344 .unwrap_or(true),
345 ),
346 }
347 }
348
349 fn evaluate_17(&self, ctx: &EvaluationContext) -> ConditionResult {
352 ctx.external.evaluate("recipient_is_lf_nb_msb")
353 }
354
355 fn evaluate_18(&self, ctx: &EvaluationContext) -> ConditionResult {
358 ctx.external.evaluate("recipient_is_lf_msb")
359 }
360
361 fn evaluate_19(&self, ctx: &EvaluationContext) -> ConditionResult {
364 ctx.external.evaluate("recipient_is_lf_msb_nb_uenb")
365 }
366
367 fn evaluate_20(&self, ctx: &EvaluationContext) -> ConditionResult {
370 ctx.external.evaluate("recipient_is_lf_msb_uenb")
371 }
372
373 fn evaluate_21(&self, ctx: &EvaluationContext) -> ConditionResult {
376 ctx.external.evaluate("recipient_is_lf_nb_esa")
377 }
378
379 fn evaluate_22(&self, ctx: &EvaluationContext) -> ConditionResult {
382 ctx.external.evaluate("recipient_is_msb")
383 }
384
385 fn evaluate_23(&self, ctx: &EvaluationContext) -> ConditionResult {
388 ctx.external.evaluate("recipient_is_nb_uenb")
389 }
390
391 fn evaluate_24(&self, ctx: &EvaluationContext) -> ConditionResult {
394 ctx.external.evaluate("recipient_is_nb_lf_msb_esa")
395 }
396
397 fn evaluate_25(&self, ctx: &EvaluationContext) -> ConditionResult {
400 ctx.external.evaluate("recipient_is_nb")
401 }
402
403 fn evaluate_26(&self, ctx: &EvaluationContext) -> ConditionResult {
406 ctx.external.evaluate("recipient_is_nb_lf_bkv_biko")
407 }
408
409 fn evaluate_27(&self, ctx: &EvaluationContext) -> ConditionResult {
411 ctx.has_qualified_value("NAD", 0, "Z31", 8, 0, &["DE"])
412 }
413
414 fn evaluate_28(&self, ctx: &EvaluationContext) -> ConditionResult {
416 ctx.has_qualified_value("NAD", 0, "Z34", 8, 0, &["DE"])
417 }
418
419 fn evaluate_29(&self, ctx: &EvaluationContext) -> ConditionResult {
421 ctx.has_qualified_value("NAD", 0, "Z35", 8, 0, &["DE"])
422 }
423
424 fn evaluate_30(&self, ctx: &EvaluationContext) -> ConditionResult {
426 ctx.has_qualified_value("NAD", 0, "Z36", 8, 0, &["DE"])
427 }
428
429 fn evaluate_31(&self, ctx: &EvaluationContext) -> ConditionResult {
431 match ctx.has_qualified_value("NAD", 0, "Z31", 8, 0, &["DE"]) {
432 ConditionResult::True => ConditionResult::False,
433 ConditionResult::False => ConditionResult::True,
434 ConditionResult::Unknown => ConditionResult::Unknown,
435 }
436 }
437
438 fn evaluate_32(&self, ctx: &EvaluationContext) -> ConditionResult {
440 let nads = ctx.find_segments_with_qualifier("NAD", 0, "Z34");
441 if nads.is_empty() {
442 return ConditionResult::True;
443 }
444 let has_de = nads.iter().any(|s| {
445 s.elements
446 .get(8)
447 .and_then(|e| e.first())
448 .is_some_and(|v| v == "DE")
449 });
450 ConditionResult::from(!has_de)
451 }
452
453 fn evaluate_33(&self, ctx: &EvaluationContext) -> ConditionResult {
455 let nads = ctx.find_segments_with_qualifier("NAD", 0, "Z35");
456 if nads.is_empty() {
457 return ConditionResult::True;
458 }
459 let has_de = nads.iter().any(|s| {
460 s.elements
461 .get(8)
462 .and_then(|e| e.first())
463 .is_some_and(|v| v == "DE")
464 });
465 ConditionResult::from(!has_de)
466 }
467
468 fn evaluate_34(&self, ctx: &EvaluationContext) -> ConditionResult {
470 let nads = ctx.find_segments_with_qualifier("NAD", 0, "Z36");
471 if nads.is_empty() {
472 return ConditionResult::True;
473 }
474 let has_de = nads.iter().any(|s| {
475 s.elements
476 .get(8)
477 .and_then(|e| e.first())
478 .is_some_and(|v| v == "DE")
479 });
480 ConditionResult::from(!has_de)
481 }
482
483 fn evaluate_35(&self, ctx: &EvaluationContext) -> ConditionResult {
486 ctx.external.evaluate("recipient_is_uenb")
487 }
488
489 fn evaluate_36(&self, ctx: &EvaluationContext) -> ConditionResult {
492 ctx.external.evaluate("recipient_is_bkv")
493 }
494
495 fn evaluate_490(&self, ctx: &EvaluationContext) -> ConditionResult {
497 match ctx.resolved_value {
498 Some(val) => is_mesz_utc(val),
499 None => ConditionResult::False,
500 }
501 }
502
503 fn evaluate_491(&self, ctx: &EvaluationContext) -> ConditionResult {
505 match ctx.resolved_value {
506 Some(val) => is_mez_utc(val),
507 None => ConditionResult::False,
508 }
509 }
510
511 fn evaluate_494(&self, _ctx: &EvaluationContext) -> ConditionResult {
514 ConditionResult::True
518 }
519
520 fn evaluate_500(&self, _ctx: &EvaluationContext) -> ConditionResult {
522 ConditionResult::True
525 }
526
527 fn evaluate_501(&self, _ctx: &EvaluationContext) -> ConditionResult {
529 ConditionResult::True
532 }
533
534 fn evaluate_502(&self, _ctx: &EvaluationContext) -> ConditionResult {
536 ConditionResult::True
539 }
540
541 fn evaluate_503(&self, _ctx: &EvaluationContext) -> ConditionResult {
543 ConditionResult::True
545 }
546
547 fn evaluate_504(&self, _ctx: &EvaluationContext) -> ConditionResult {
549 ConditionResult::True
551 }
552
553 fn evaluate_505(&self, ctx: &EvaluationContext) -> ConditionResult {
556 let acw_segments = ctx.find_segments_with_qualifier("RFF", 0, "ACW");
557 if acw_segments.is_empty() {
558 return ConditionResult::False;
559 }
560 let agk_segments = ctx.find_segments_with_qualifier("RFF", 0, "AGK");
561 let current_version = agk_segments
562 .first()
563 .and_then(|s| s.elements.first())
564 .and_then(|e| e.get(3))
565 .and_then(|v| v.parse::<i64>().ok());
566 let predecessor_version = acw_segments
567 .first()
568 .and_then(|s| s.elements.first())
569 .and_then(|e| e.get(3))
570 .and_then(|v| v.parse::<i64>().ok());
571 match (current_version, predecessor_version) {
572 (Some(cur), Some(pred)) => ConditionResult::from(cur >= pred + 1),
573 _ => ConditionResult::Unknown,
574 }
575 }
576
577 fn evaluate_506(&self, _ctx: &EvaluationContext) -> ConditionResult {
579 ConditionResult::True
581 }
582
583 fn evaluate_508(&self, _ctx: &EvaluationContext) -> ConditionResult {
585 ConditionResult::True
587 }
588
589 fn evaluate_908(&self, _ctx: &EvaluationContext) -> ConditionResult {
591 ConditionResult::True
593 }
594
595 fn evaluate_931(&self, ctx: &EvaluationContext) -> ConditionResult {
597 ctx.format_check("DTM", 0, 1, validate_timezone_utc)
598 }
599
600 fn evaluate_932(&self, ctx: &EvaluationContext) -> ConditionResult {
602 ctx.format_check("DTM", 0, 1, |val| validate_hhmm_equals(val, "2200"))
603 }
604
605 fn evaluate_933(&self, ctx: &EvaluationContext) -> ConditionResult {
607 ctx.format_check("DTM", 0, 1, |val| validate_hhmm_equals(val, "2300"))
608 }
609
610 fn evaluate_939(&self, ctx: &EvaluationContext) -> ConditionResult {
612 ctx.format_check("COM", 0, 0, validate_email)
613 }
614
615 fn evaluate_940(&self, ctx: &EvaluationContext) -> ConditionResult {
617 ctx.format_check("COM", 0, 0, validate_phone)
618 }
619}