Skip to main content

CustomRulePack

Struct CustomRulePack 

Source
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

Source

pub fn new(name: impl Into<String>) -> Self

Create an empty rule pack with a human-readable name used in rule IDs.

Source

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.

Source

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.

Source

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.

Source

pub fn add_group_rule<F>( self, group_id: impl Into<Arc<str>>, rule_id: impl Into<Arc<str>>, rule: F, ) -> Self
where F: Fn(usize, &[Segment<'_>], &mut Vec<ValidationIssue>) + Send + Sync + 'static,

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 (first SG5 = 0, second SG5 = 1, …).
  • segs — the flat slice of edifact_rs::Segment values contained within this group occurrence. Only segments that belong to this occurrence are included; no additional filtering is needed.
  • issues — append ValidationIssue values 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"),
            );
        }
    });
Source

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");
Source

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");
Source

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"]);
Source

pub fn check_format<F>( self, tag: &'static str, element_index: usize, component_index: usize, validator: F, description: &'static str, ) -> Self
where F: Fn(&str) -> bool + Send + Sync + 'static,

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 ':')");
Source

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");

Trait Implementations§

Source§

impl Debug for CustomRulePack

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.