pub struct CustomRulePack(/* private fields */);Expand description
A caller-supplied validation rule pack that can be merged on top of all
built-in validation layers when calling EdiEnergyMessage::validate_with_pack.
CustomRulePack insulates callers from the internal edifact-rs
ProfileRulePack type: no direct dependency on edifact-rs is required
to construct a CustomRulePack.
§Example
use edi_energy::CustomRulePack;
let pack = CustomRulePack::new("my-business-rules")
.require_segment("STS")
.forbid_segment("CNT");Implementations§
Source§impl CustomRulePack
impl CustomRulePack
Sourcepub fn new(name: impl Into<String>) -> Self
pub fn new(name: impl Into<String>) -> Self
Create an empty rule pack with a human-readable name used in rule IDs.
Sourcepub fn require_segment(self, tag: &'static str) -> Self
pub fn require_segment(self, tag: &'static str) -> Self
Add a rule that requires the given EDIFACT segment tag to be present at least once. Emits an error-severity issue when the segment is absent.
Sourcepub fn forbid_segment(self, tag: &'static str) -> Self
pub fn forbid_segment(self, tag: &'static str) -> Self
Add a rule that forbids the given EDIFACT segment tag. Emits an error-severity issue when the segment is present.
Sourcepub fn require_qualifier(
self,
tag: &'static str,
allowed: &'static [&'static str],
) -> Self
pub fn require_qualifier( self, tag: &'static str, allowed: &'static [&'static str], ) -> Self
Add a rule that requires the given segment’s first element (element 0,
component 0) to be present and contain one of the allowed qualifier values.
Emits an error-severity issue when the qualifier is absent or not in the set.
Sourcepub fn add_group_rule<F>(
self,
group_id: impl Into<Arc<str>>,
rule_id: impl Into<Arc<str>>,
rule: F,
) -> Self
pub fn add_group_rule<F>( self, group_id: impl Into<Arc<str>>, rule_id: impl Into<Arc<str>>, rule: F, ) -> Self
Add a rule that is evaluated once per occurrence of the named segment group
(e.g. "SG2", "SG5").
The closure receives:
occurrence— 0-based index of this group occurrence within its parent (firstSG5= 0, secondSG5= 1, …).segs— the flat slice ofedifact_rs::Segmentvalues contained within this group occurrence. Only segments that belong to this occurrence are included; no additional filtering is needed.issues— appendValidationIssuevalues here to report violations.
The group_id must match a group name defined in the message type’s MIG
(e.g. "SG2" for UTILMD, "SG6" for MSCONS). If no group with that ID
exists in the validated message, the rule is silently skipped.
§Example
use edi_energy::CustomRulePack;
use edifact_rs::{ValidationIssue, ValidationSeverity};
// Require that every SG5 occurrence in MSCONS contains at least one LOC.
let pack = CustomRulePack::new("my-mscons-rules")
.add_group_rule("SG6", "MY-SG6-LOC-REQ", |_occ, segs, issues| {
if !segs.iter().any(|s| s.tag == "LOC") {
issues.push(
ValidationIssue::new(
ValidationSeverity::Error,
"SG6 group is missing required LOC segment".to_owned(),
)
.with_rule_id("MY-SG6-LOC-REQ"),
);
}
});Sourcepub fn require_segment_in_group(
self,
group_id: impl Into<Arc<str>>,
tag: &'static str,
) -> Self
pub fn require_segment_in_group( self, group_id: impl Into<Arc<str>>, tag: &'static str, ) -> Self
Add a rule that requires the given segment tag to be present in every occurrence of the named segment group.
Emits an Error-severity issue when the segment is absent from a group
occurrence. The auto-generated rule ID is CUSTOM-{group_id}-{tag}-REQUIRED.
§Example
use edi_energy::CustomRulePack;
// Every SG2 in UTILMD must contain a NAD segment.
let pack = CustomRulePack::new("my-rules")
.require_segment_in_group("SG2", "NAD");Sourcepub fn forbid_segment_in_group(
self,
group_id: impl Into<Arc<str>>,
tag: &'static str,
) -> Self
pub fn forbid_segment_in_group( self, group_id: impl Into<Arc<str>>, tag: &'static str, ) -> Self
Add a rule that forbids the given segment tag from appearing in any occurrence of the named segment group.
Emits an Error-severity issue for each occurrence found, with the
source byte span attached for precise diagnostic highlighting.
The auto-generated rule ID is CUSTOM-{group_id}-{tag}-FORBIDDEN.
§Example
use edi_energy::CustomRulePack;
// SG4 must not contain a FTX segment for this process.
let pack = CustomRulePack::new("my-rules")
.forbid_segment_in_group("SG4", "FTX");Sourcepub fn check_element(
self,
tag: &'static str,
element_index: usize,
component_index: usize,
allowed: &'static [&'static str],
) -> Self
pub fn check_element( self, tag: &'static str, element_index: usize, component_index: usize, allowed: &'static [&'static str], ) -> Self
Add a rule that checks the value at a specific element and component position of the given segment tag.
This is a generalisation of require_qualifier that
works at any (element_index, component_index) position rather than only the
first qualifier element.
§Example
use edi_energy::CustomRulePack;
// Require that CCI element 2 component 0 is one of the approved codes.
let pack = CustomRulePack::new("my-rules")
.check_element("CCI", 2, 0, &["Z01", "Z02"]);Sourcepub fn check_format<F>(
self,
tag: &'static str,
element_index: usize,
component_index: usize,
validator: F,
description: &'static str,
) -> Self
pub fn check_format<F>( self, tag: &'static str, element_index: usize, component_index: usize, validator: F, description: &'static str, ) -> Self
Add a rule that validates the value at a specific element position using a caller-supplied predicate function.
Use this to enforce format constraints that cannot be expressed as a fixed code list — for example OBIS code structure, GLN check-digit, or date format.
The description string is included in the error message to describe the
expected format (e.g. "OBIS code (format: A-B:C.D.E*F)").
§Example
use edi_energy::CustomRulePack;
// Require that PIA element 1 component 0 looks like an OBIS code.
let pack = CustomRulePack::new("my-rules")
.check_format("PIA", 1, 0, |v| v.contains(':'), "OBIS code (must contain ':')");Sourcepub fn require_segment_combination(
self,
tag_a: &'static str,
tag_b: &'static str,
) -> Self
pub fn require_segment_combination( self, tag_a: &'static str, tag_b: &'static str, ) -> Self
Add a rule that requires both tag_a and tag_b to be present together.
Emits an error if tag_a is present but tag_b is absent, or vice versa.
Use this for segments that must always appear in pairs (e.g. CTA and COM
in contact-information patterns).
§Example
use edi_energy::CustomRulePack;
let pack = CustomRulePack::new("my-rules")
.require_segment_combination("CTA", "COM");