cimoxide-validation 0.3.3

SHACL validation of CGMES datasets against the ENTSO-E profile constraints
Documentation
// Generated by cimgen — do not edit by hand.
#![allow(clippy::all, dead_code, unused)]
use cimdecoder::CimDataset;
use crate::Violation;
use crate::helpers::*;

pub fn validate_p61970_452_operation_ap_con_complex_shacl(dataset: &CimDataset) -> Vec<Violation> {
    let mut v = Vec::new();
    v.extend(check_p61970_452_operation_ap_con_complex_shacl_accumulator_measurement_measurement_type_in(dataset));
    v.extend(check_p61970_452_operation_ap_con_complex_shacl_accumulator_measurement_unit_symbol_in(dataset));
    v.extend(check_p61970_452_operation_ap_con_complex_shacl_analog_measurement_measurement_type_in(dataset));
    v.extend(check_p61970_452_operation_ap_con_complex_shacl_analog_measurement_unit_symbol_in(dataset));
    v.extend(check_p61970_452_operation_ap_con_complex_shacl_discrete_measurement_measurement_type_has_value(dataset));
    v.extend(check_p61970_452_operation_ap_con_complex_shacl_discrete_measurement_unit_symbol_has_value(dataset));
    v.extend(check_p61970_452_operation_ap_con_complex_shacl_measurement_value_source_identified_object_name_in(dataset));
    v
}

pub fn check_p61970_452_operation_ap_con_complex_shacl_accumulator_measurement_measurement_type_in(dataset: &CimDataset) -> Vec<Violation> {
    let mut violations = Vec::new();
    const ALLOWED: &[&str] = &["ApparentEnergy", "ReactiveEnergy", "ActiveEnergy"];
    for mrid in dataset.by_type.get("Accumulator").into_iter().flatten() {
        let entry = &dataset.entries[mrid];
        let obj = match entry.element.as_any()
            .downcast_ref::<cimstructs::Accumulator>() {
            Some(o) => o, None => continue,
        };
        if obj.base.measurement_type.is_empty() { continue; }
        if !ALLOWED.contains(&obj.base.measurement_type.as_str()) {
            violations.push(Violation {
                object_id:   mrid.clone(),
                rule_id:     "op452:Accumulator-accumulatorValues".to_string(),
                class:       "Accumulator".to_string(),
                property:    "Measurement.measurementType".to_string(),
                message:     "Not allowed value.".to_string(),
                severity:    "sh:Violation".to_string(),
                name:        "C:452:OP:Measurement.measurementType:accumulatorValues".to_string(),
                description: "For Accumulator, Measurement.measurementType is restricted to the following valid values: ApparentEnergy, ReactiveEnergy, ActiveEnergy.".to_string(),
            });
        }
    }
    violations
}

pub fn check_p61970_452_operation_ap_con_complex_shacl_accumulator_measurement_unit_symbol_in(dataset: &CimDataset) -> Vec<Violation> {
    let mut violations = Vec::new();
    const ALLOWED: &[&str] = &["UnitSymbol.VAh", "UnitSymbol.VArh", "UnitSymbol.Wh"];
    for mrid in dataset.by_type.get("Accumulator").into_iter().flatten() {
        let entry = &dataset.entries[mrid];
        let obj = match entry.element.as_any()
            .downcast_ref::<cimstructs::Accumulator>() {
            Some(o) => o, None => continue,
        };
        if obj.base.unit_symbol.is_none() { continue; }
        if !ALLOWED.contains(&obj.base.unit_symbol.as_ref().map_or("", |u| u.uri.as_str())) {
            violations.push(Violation {
                object_id:   mrid.clone(),
                rule_id:     "op452:Accumulator-accumulatorUnitValues".to_string(),
                class:       "Accumulator".to_string(),
                property:    "Measurement.unitSymbol".to_string(),
                message:     "Not allowed value.".to_string(),
                severity:    "sh:Violation".to_string(),
                name:        "C:452:OP:Measurement.unitSymbol:accumulatorValues".to_string(),
                description: "For Accumulator, Measurement.unitSymbol is restricted to the following valid values: VAh, VArh, Wh.".to_string(),
            });
        }
    }
    violations
}

pub fn check_p61970_452_operation_ap_con_complex_shacl_analog_measurement_measurement_type_in(dataset: &CimDataset) -> Vec<Violation> {
    let mut violations = Vec::new();
    const ALLOWED: &[&str] = &["ThreePhasePower", "ThreePhaseActivePower", "ThreePhaseReactivePower", "LineCurrent", "PhaseVoltage", "Voltage", "Angle", "Frequency", "TapPosition"];
    for mrid in dataset.by_type.get("Analog").into_iter().flatten() {
        let entry = &dataset.entries[mrid];
        let obj = match entry.element.as_any()
            .downcast_ref::<cimstructs::Analog>() {
            Some(o) => o, None => continue,
        };
        if obj.base.measurement_type.is_empty() { continue; }
        if !ALLOWED.contains(&obj.base.measurement_type.as_str()) {
            violations.push(Violation {
                object_id:   mrid.clone(),
                rule_id:     "op452:Analog-analogValues".to_string(),
                class:       "Analog".to_string(),
                property:    "Measurement.measurementType".to_string(),
                message:     "Not allowed value.".to_string(),
                severity:    "sh:Violation".to_string(),
                name:        "C:452:OP:Measurement.measurementType:analogValues".to_string(),
                description: "For Analog, Measurement.measurementType is restricted to the following valid values: ThreePhasePower, ThreePhaseActivePower, ThreePhaseReactivePower, LineCurrent, PhaseVoltage, Voltage, Angle, Frequency and TapPosition.".to_string(),
            });
        }
    }
    violations
}

pub fn check_p61970_452_operation_ap_con_complex_shacl_analog_measurement_unit_symbol_in(dataset: &CimDataset) -> Vec<Violation> {
    let mut violations = Vec::new();
    const ALLOWED: &[&str] = &["UnitSymbol.W", "UnitSymbol.deg", "UnitSymbol.VA", "UnitSymbol.A", "UnitSymbol.VAr", "UnitSymbol.V", "UnitSymbol.Hz"];
    for mrid in dataset.by_type.get("Analog").into_iter().flatten() {
        let entry = &dataset.entries[mrid];
        let obj = match entry.element.as_any()
            .downcast_ref::<cimstructs::Analog>() {
            Some(o) => o, None => continue,
        };
        if obj.base.unit_symbol.is_none() { continue; }
        if !ALLOWED.contains(&obj.base.unit_symbol.as_ref().map_or("", |u| u.uri.as_str())) {
            violations.push(Violation {
                object_id:   mrid.clone(),
                rule_id:     "op452:Analog-analogUnitValues".to_string(),
                class:       "Analog".to_string(),
                property:    "Measurement.unitSymbol".to_string(),
                message:     "Not allowed value.".to_string(),
                severity:    "sh:Violation".to_string(),
                name:        "C:452:OP:Measurement.unitSymbol:analogValues".to_string(),
                description: "For Analog, Measurement.unitSymbol is restricted to the following valid values: W, deg, VA, A, VAr, V, Hz.".to_string(),
            });
        }
    }
    violations
}

pub fn check_p61970_452_operation_ap_con_complex_shacl_discrete_measurement_measurement_type_has_value(dataset: &CimDataset) -> Vec<Violation> {
    let mut violations = Vec::new();
    for mrid in dataset.by_type.get("Discrete").into_iter().flatten() {
        let entry = &dataset.entries[mrid];
        let obj = match entry.element.as_any()
            .downcast_ref::<cimstructs::Discrete>() {
            Some(o) => o, None => continue,
        };
        if obj.base.measurement_type.is_empty() { continue; }
        if obj.base.measurement_type != "SwitchPosition" {
            violations.push(Violation {
                object_id:   mrid.clone(),
                rule_id:     "op452:Discrete-discreteValues".to_string(),
                class:       "Discrete".to_string(),
                property:    "Measurement.measurementType".to_string(),
                message:     "Not allowed value.".to_string(),
                severity:    "sh:Violation".to_string(),
                name:        "C:452:OP:Measurement.measurementType:discreteValues".to_string(),
                description: "For Discrete, Measurement.measurementType is restricted to the following valid values: SwitchPosition.".to_string(),
            });
        }
    }
    violations
}

pub fn check_p61970_452_operation_ap_con_complex_shacl_discrete_measurement_unit_symbol_has_value(dataset: &CimDataset) -> Vec<Violation> {
    let mut violations = Vec::new();
    for mrid in dataset.by_type.get("Discrete").into_iter().flatten() {
        let entry = &dataset.entries[mrid];
        let obj = match entry.element.as_any()
            .downcast_ref::<cimstructs::Discrete>() {
            Some(o) => o, None => continue,
        };
        if obj.base.unit_symbol.as_ref().map_or(true, |u| u.uri != "UnitSymbol.none") {
            violations.push(Violation {
                object_id:   mrid.clone(),
                rule_id:     "op452:Discrete-discreteUnitValues".to_string(),
                class:       "Discrete".to_string(),
                property:    "Measurement.unitSymbol".to_string(),
                message:     "Not allowed value.".to_string(),
                severity:    "sh:Violation".to_string(),
                name:        "C:452:OP:Measurement.unitSymbol:discreteValues".to_string(),
                description: "For Discrete, Measurement.unitSymbol is restricted to the following valid values: none.".to_string(),
            });
        }
    }
    violations
}

pub fn check_p61970_452_operation_ap_con_complex_shacl_measurement_value_source_identified_object_name_in(dataset: &CimDataset) -> Vec<Violation> {
    let mut violations = Vec::new();
    const ALLOWED: &[&str] = &["ICCP", "SCADA"];
    for mrid in dataset.by_type.get("MeasurementValueSource").into_iter().flatten() {
        let entry = &dataset.entries[mrid];
        let obj = match entry.element.as_any()
            .downcast_ref::<cimstructs::MeasurementValueSource>() {
            Some(o) => o, None => continue,
        };
        if obj.base.name.is_empty() { continue; }
        if !ALLOWED.contains(&obj.base.name.as_str()) {
            violations.push(Violation {
                object_id:   mrid.clone(),
                rule_id:     "op452:MeasurementValueSource-name".to_string(),
                class:       "MeasurementValueSource".to_string(),
                property:    "IdentifiedObject.name".to_string(),
                message:     "Not allowed value.".to_string(),
                severity:    "sh:Violation".to_string(),
                name:        "C:452:OP:MeasurementValueSource:name".to_string(),
                description: "For MeasurementValueSource, attribute IdentifiedObject.name is restricted to the following strings for MeasurementValueSource: ICCP, SCADA.".to_string(),
            });
        }
    }
    violations
}