#![allow(clippy::style, clippy::complexity)]
#[allow(unused_imports)]
use crate::eval::format_validators::*;
use crate::eval::{ConditionEvaluator, ConditionResult, EvaluationContext};
use crate::generated::fv2510::UtilmdStromConditionEvaluatorFV2510;
use mig_types::segment::OwnedSegment;
pub struct UtilmdStromConditionEvaluatorFV2604 {
fallback: UtilmdStromConditionEvaluatorFV2510,
}
impl Default for UtilmdStromConditionEvaluatorFV2604 {
fn default() -> Self {
Self {
fallback: UtilmdStromConditionEvaluatorFV2510::default(),
}
}
}
const FV2604_OVERRIDES: &[u32] = &[160, 182, 183, 203, 271];
impl ConditionEvaluator for UtilmdStromConditionEvaluatorFV2604 {
fn message_type(&self) -> &str {
"UTILMD_Strom"
}
fn format_version(&self) -> &str {
"FV2604"
}
fn evaluate(&self, condition: u32, ctx: &EvaluationContext) -> ConditionResult {
match condition {
160 => self.evaluate_160(ctx),
182 => self.evaluate_182(ctx),
183 => self.evaluate_183(ctx),
203 => self.evaluate_203(ctx),
271 => self.evaluate_271(ctx),
other => self.fallback.evaluate(other, ctx),
}
}
fn is_external(&self, condition: u32) -> bool {
!FV2604_OVERRIDES.contains(&condition) && self.fallback.is_external(condition)
}
fn is_known(&self, condition: u32) -> bool {
FV2604_OVERRIDES.contains(&condition) || self.fallback.is_known(condition)
}
}
fn sg10_has(
ctx: &EvaluationContext,
pred: impl Fn(&[OwnedSegment], &[OwnedSegment]) -> bool,
) -> ConditionResult {
let Some(nav) = ctx.navigator() else {
let ccis: Vec<OwnedSegment> = ctx.find_segments("CCI").into_iter().cloned().collect();
let cavs: Vec<OwnedSegment> = ctx.find_segments("CAV").into_iter().cloned().collect();
return ConditionResult::from(pred(&ccis, &cavs));
};
for i in 0..nav.group_instance_count(&["SG4", "SG8"]) {
for j in 0..nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10") {
let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
let cavs = nav.find_segments_in_child_group("CAV", &["SG4", "SG8"], i, "SG10", j);
if pred(&ccis, &cavs) {
return ConditionResult::True;
}
}
}
ConditionResult::False
}
impl UtilmdStromConditionEvaluatorFV2604 {
fn evaluate_160(&self, ctx: &EvaluationContext) -> ConditionResult {
let nav = match ctx.navigator() {
Some(n) => n,
None => return ConditionResult::Unknown,
};
let mut seen = std::collections::BTreeSet::new();
for i in 0..nav.group_instance_count(&["SG4", "SG8"]) {
let seqs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
let Some(seq) = seqs.first() else { continue };
let code = seq
.elements
.first()
.and_then(|e| e.first())
.cloned()
.unwrap_or_default();
if !["Z58", "ZC9", "ZD0", "ZD6"].contains(&code.as_str()) {
continue;
}
let zeitraum = seq
.elements
.get(1)
.and_then(|e| e.first())
.cloned()
.unwrap_or_default();
for rff in
nav.find_segments_with_qualifier_in_group("RFF", 0, "Z33", &["SG4", "SG8"], i)
{
let objekt = rff
.elements
.first()
.and_then(|e| e.get(1))
.cloned()
.unwrap_or_default();
if !seen.insert((zeitraum.clone(), code.clone(), objekt)) {
return ConditionResult::True;
}
}
}
ConditionResult::False
}
fn evaluate_182(&self, ctx: &EvaluationContext) -> ConditionResult {
sg10_has(ctx, |ccis, cavs| {
ccis.iter().any(|s| {
s.elements
.get(2)
.and_then(|e| e.first())
.is_some_and(|v| v == "ZA6")
}) && cavs.iter().any(|s| {
s.elements
.first()
.and_then(|e| e.first())
.is_some_and(|v| v == "E14")
})
})
}
fn evaluate_183(&self, ctx: &EvaluationContext) -> ConditionResult {
sg10_has(ctx, |ccis, _| {
ccis.iter().any(|s| {
s.elements
.first()
.and_then(|e| e.first())
.is_some_and(|v| v == "Z30")
&& s.elements
.get(2)
.and_then(|e| e.first())
.is_some_and(|v| v == "Z07")
})
})
}
fn evaluate_203(&self, ctx: &EvaluationContext) -> ConditionResult {
ctx.has_qualified_value(
"STS",
0,
"7",
2,
0,
&["E06", "Z39", "ZC6", "ZC7", "ZT6", "ZT7", "Z02", "ZZD"],
)
}
fn evaluate_271(&self, ctx: &EvaluationContext) -> ConditionResult {
let shared = ctx.groups_share_qualified_value(
"RFF",
0,
"Z50",
0,
2,
&["SG4", "SG6"],
"RFF",
0,
2,
&["SG4", "SG8"],
);
let messtechnik = sg10_has(ctx, |ccis, cavs| {
ccis.iter().any(|s| {
s.elements
.get(2)
.and_then(|e| e.first())
.is_some_and(|v| v == "Z83")
}) && cavs.iter().any(|s| {
s.elements
.first()
.and_then(|e| e.first())
.is_some_and(|v| v == "Z53")
})
});
shared.and(messtechnik)
}
}