pub trait SegmentLayout {
// Required methods
fn layout_tag(&self) -> &str;
fn resolve_code(
&self,
data_element: &str,
) -> Result<ElementPath, EdifactError>;
fn slots(&self) -> Vec<LayoutSlot>;
// Provided method
fn audit(&self, segments: &[Segment<'_>]) -> LayoutAudit { ... }
}Expand description
Directory metadata that maps UN/EDIFACT data element identifiers to positions.
Implemented by SegmentDefinition (compile-time tables) and
OwnedSegmentDef (runtime-loaded definitions), so the same code-addressed
accessors work against either source.
§Example
use edifact_rs::{ElementRef, SegmentDefinition, SegmentLayout, Status};
static BGM_ELEMENTS: &[ElementRef] = &[
ElementRef::new(1, "C002", Status::Conditional, 1),
ElementRef::new(2, "C106", Status::Conditional, 1),
ElementRef::new(3, "1225", Status::Conditional, 1),
];
static BGM: SegmentDefinition =
SegmentDefinition::new("BGM", "Beginning of message", BGM_ELEMENTS);
let path = BGM.resolve_code("1225")?;
assert_eq!(path.element, 2);
assert!(BGM.resolve_code("9999").is_err());Required Methods§
Sourcefn layout_tag(&self) -> &str
fn layout_tag(&self) -> &str
The segment tag this layout describes (e.g. "NAD").
Sourcefn resolve_code(&self, data_element: &str) -> Result<ElementPath, EdifactError>
fn resolve_code(&self, data_element: &str) -> Result<ElementPath, EdifactError>
Resolve a UN/EDIFACT data element identifier to a position.
§Errors
Returns EdifactError::UnknownDataElement when the identifier does not
appear in this definition, and EdifactError::AmbiguousDataElement
when it appears at more than one position.
Sourcefn slots(&self) -> Vec<LayoutSlot>
fn slots(&self) -> Vec<LayoutSlot>
Every position this layout declares, flattened and in order.
Implemented by both the compile-time and runtime definitions, so tooling can walk a layout without knowing which one it holds.
Provided Methods§
Sourcefn audit(&self, segments: &[Segment<'_>]) -> LayoutAudit
fn audit(&self, segments: &[Segment<'_>]) -> LayoutAudit
Check this layout against real messages and report what does not line up.
Hand-authoring a segment definition has a silent failure mode: a layout
that disagrees with the wire resolves value_by_code to the wrong
component, returns a plausible value, and every test still passes. There
is no way to notice from inside the program — the definition is the only
thing that says what the positions mean.
Pointing the definition at a corpus is what breaks that circle. Three kinds of finding come back, and the third is the one that matters most:
| Finding | Means |
|---|---|
UndeclaredElement / UndeclaredComponent | The wire carries a value the layout has no slot for — the layout is wrong. |
MandatoryNeverPopulated | A slot the layout calls mandatory is empty everywhere — the status or the position is wrong. |
NeverObserved | Nothing in the corpus reaches this slot, so the corpus cannot confirm it. |
NeverObserved is not a defect. It is the honest answer to “does my
definition match the directory?” when the fixtures are too thin to tell,
and it names exactly which positions to go and check by hand.
Only segments whose tag matches layout_tag are
examined; the rest of the slice is ignored, so a whole interchange can be
passed in as-is.
§Example
use edifact_rs::{ComponentRef, ElementRef, SegmentDefinition, SegmentLayout, Status, from_bytes};
// A hand-authored C507 that stops one component short of the directory.
static C507: &[ComponentRef] = &[
ComponentRef::new(1, "2005", Status::Mandatory),
ComponentRef::new(2, "2380", Status::Conditional),
];
static DTM_ELEMENTS: &[ElementRef] =
&[ElementRef::composite(1, "C507", Status::Mandatory, 1, C507)];
static DTM: SegmentDefinition =
SegmentDefinition::new("DTM", "Date/time/period", DTM_ELEMENTS);
let corpus: Vec<_> = from_bytes(b"DTM+137:20260101:102'").collect::<Result<Vec<_>, _>>()?;
let audit = DTM.audit(&corpus);
// The format qualifier `102` has nowhere to go — the layout is short.
assert!(audit.has_contradictions());
assert_eq!(audit.segments_examined(), 1);Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".