Skip to main content

Crate edifact_rs

Crate edifact_rs 

Source
Expand description

edifact-rs — zero-copy EDIFACT tokenizer, parser, writer, serde traits, validation engine, and extensible directory support.

edifact-rs is the main entry point of this workspace. The core parsing, writing, and validation infrastructure is always available. Custom directory validators can be implemented by downstream crates or generated through external build tooling.

§Quick start

use edifact_rs::from_bytes;
let input = b"UNB+UNOA:1+SENDER+RECEIVER+200101:0900+1'UNZ+0+1'";
let segments: Vec<_> = from_bytes(input).collect::<Result<_, _>>().unwrap();
assert_eq!(segments[0].tag, "UNB");

§Crate features

  • derive (enabled by default): re-exports the derive macros from edifact-rs-derive.
  • diagnostics (disabled by default): enables rich diagnostic output via miette. When enabled, errors implement miette::Diagnostic for enhanced error reporting. This feature adds an optional dependency and has no impact on parsing performance.

The crate is expected to compile both with defaults and with --no-default-features for consumers who only want the core parsing and writing functionality.

§Feature matrix workflows

  • default features: cargo test -p edifact-rs
  • no default features: cargo test -p edifact-rs --no-default-features
  • all features: cargo test -p edifact-rs --all-features

§Diagnostic Feature

When the diagnostics feature is enabled, EdifactError gains additional traits and methods that enable rich, human-readable error output:

Error: invalid delimiter byte 0xAB at offset 42

 ╭─ input.edi:2:3
 │
 2 │ UNB+UNOA:1+....[invalid]...
 │         ^^^ invalid byte here
 │
Error Code: E002
Help: The byte 0xAB is not a valid delimiter. Check UNA configuration

This feature is useful for CLI tools and error reporting, but is not required for applications that handle errors programmatically.

§Parse And Text Contracts

Parsing in edifact-rs is strict and deterministic:

  • Segment and element text must decode as UTF-8 (E003 on failure).
  • Release characters must escape exactly one following byte. A trailing ? at end-of-input is rejected (E019).
  • Malformed delimiters and truncated segments are reported with stable error codes rather than panicking.

These contracts apply to both slice-based parsing (from_bytes) and reader-based parsing (from_reader).

use edifact_rs::from_reader;
use std::io::Cursor;

let input = b"UNA:;.? 'BGM;220;test?;value'";
let segments = from_reader(Cursor::new(&input[..])).unwrap();
assert_eq!(segments.len(), 1);
assert_eq!(segments[0].tag, "BGM");
assert_eq!(segments[0].elements[0].components[0], "220");
assert_eq!(segments[0].elements[1].components[0], "test;value");

§Validation Quick Start

The Validator trait and ValidationContext provide a flexible framework for building custom validators. Users can generate validators from official UNECE sources or implement their own.

See the Validator trait documentation and the cookbook_fixture_validation.rs example for details on creating custom validators.

§Custom Profile Packs

ProfileRulePack is the extension point for downstream MIG/profile crates. Packs can be authored with public APIs only and plugged into a ValidationContext:

use edifact_rs::{
    from_bytes, ProfileRulePack, ValidationContext, ValidationIssue, ValidationSeverity,
};

let segments: Vec<_> = from_bytes(b"UNH+1+ORDERS:D:96A:UN'BGM+220+PO123+9'UNT+3+1'")
    .collect::<Result<_, _>>()?;

let pack = ProfileRulePack::builder("ORDERS-DEMO")
    .for_message_type("ORDERS")
    .with_rule_fn(|segments| {
        let bgm = segments.iter().find(|segment| segment.tag == "BGM")?;
        let document_code = bgm.get_element(0)?.get_component(0)?;
        (document_code == "220").then(|| {
            ValidationIssue::new(
                ValidationSeverity::Warning,
                "demo pack rejects BGM 220 for illustration",
            )
            .with_rule_id("DEMO-P001")
            .with_segment("BGM")
            .with_element_index(0)
        })
    });

let report = ValidationContext::builder()
    .with_profile_pack(pack)
    .build()
    .validate_lenient(&segments);

assert!(report.has_warnings());
let partner_report = report.filter_by_rule_prefix("DEMO-");
assert!(partner_report.total_issues() >= 1);

§Async Usage

edifact-rs does not provide a native async API. All parsing is synchronous and driven by the standard std::io::Read / std::io::BufRead traits. The recommended integration pattern with async runtimes is:

  1. Use your async runtime’s read utilities to read the entire message into a Vec<u8> (e.g. tokio::io::AsyncReadExt::read_to_end).
  2. Parse the in-memory slice with from_bytes.
// With tokio:
// let mut buf = Vec::new();
// reader.read_to_end(&mut buf).await?;
// let segments: Vec<_> = edifact_rs::from_bytes(&buf).collect::<Result<_, _>>()?;

A native zero-copy streaming async API is tracked as a future roadmap item.

Re-exports§

pub use de::CompositeElement;
pub use de::EdifactCompositeDeserialize;
pub use de::EdifactDeserialize;
pub use de::EdifactSegmentTag;
pub use de::MessageWindowsIter;
pub use de::MessageWindowsSliceIter;
pub use de::SegmentAccessor;
pub use de::deserialize;
pub use de::deserialize_all_from_reader;
pub use de::deserialize_all_streaming;
pub use de::deserialize_first_from_reader;
pub use de::deserialize_first_streaming;
pub use de::deserialize_messages_bytes;
pub use de::deserialize_messages_from_reader;
pub use de::deserialize_str;
pub use de::groups_are_contiguous_by_qualifier;
pub use de::message_windows_bytes;
pub use de::message_windows_from_reader;
pub use ser::EdifactCompositeSerialize;
pub use ser::EdifactSerialize;
pub use ser::to_bytes;
pub use ser::to_edifact_string;
pub use directory_validator::DirectoryValidator;
pub use directory_validator::ElementRef;
pub use directory_validator::SegmentDefinition;
pub use directory_validator::Status;

Modules§

de
Custom deserialization trait for EDIFACT.
directory_validator
Shared UN/EDIFACT directory validation engine used by D.11A, D.01B and D.96A.
helpers
Low-level helper functions for working with raw segments.
ser
Custom serialization trait for EDIFACT.

Structs§

BorrowedElement
Zero-allocation view of an OwnedElement.
BorrowedSegment
Zero-allocation view of an OwnedSegment.
Element
A data element, which may have one or more component values.
FromBytesIter
Iterator returned by from_bytes.
FromReaderIter
Iterator returned by from_reader_iter.
IoError
Wrapper around std::io::Error that implements PartialEq by comparing std::io::ErrorKind.
OwnedElement
Owned data element used by reader-based parsing APIs.
OwnedSegment
Owned segment used by reader-based parsing APIs.
Parser
Streaming parser over a Tokenizer.
ProfileRulePack
A profile/MIG rule pack that can be plugged into ValidationContext.
ReaderConfig
Configuration for reader-based EDIFACT parsers.
Segment
A single EDIFACT segment, borrowing its data from the source input.
ServiceStringAdvice
EDIFACT service string advice (UNA segment).
Span
A half-open byte span within an EDIFACT payload.
Tokenizer
Zero-copy tokenizer over a byte slice.
ValidationContext
Runtime validation context for progressive layered validation.
ValidationContextBuilder
Builder for ValidationContext.
ValidationIssue
A structured validation issue.
ValidationReport
A collection of validation results: errors, warnings, and info.
VecEmitter
Collects events into a Vec<OwnedEdifactEvent>.
Writer
Streaming EDIFACT writer.
WriterEmitter
Writes EDIFACT events directly to any Write implementation.

Enums§

EdifactError
All errors produced by edifact-rs.
EdifactEvent
A borrowed EDIFACT event emitted during serialization.
OwnedEdifactEvent
An owned EDIFACT event — for collection and testing (no borrowed lifetimes).
ValidationLayer
Validation layers used by ValidationContext.
ValidationSeverity
Priority level for a validation error or warning.

Traits§

EventEmitter
Trait for any sink that can consume EdifactEvents.
ProfileRule
A profile rule that can be added to a ProfileRulePack.
Validator
Pluggable validator for parsed EDIFACT segments.

Functions§

from_bufread
Parse EDIFACT from a buffered reader.
from_bufread_stream
Parse EDIFACT from a buffered reader as a streaming iterator.
from_bufread_stream_with_config
Parse EDIFACT from a buffered reader as a streaming iterator with custom config.
from_bytes
Parse input bytes into an iterator of Segments.
from_reader
Parse a reader into owned segments.
from_reader_iter
Parse a reader into owned segments as a streaming iterator.
from_reader_with_config
Parse EDIFACT from an arbitrary reader as a streaming iterator with custom config.
segments_to_bytes
Serialize segments to an owned Vec<u8>.
to_writer
Serialize segments to an std::io::Write implementation.
validate_each
Helper for per-segment validators: iterates segments, calls f for each one, and converts any Err into report entries.
validate_envelope
Validates the EDIFACT interchange envelope for the given segments.

Derive Macros§

EdifactDeserializederive
Derive edifact_rs::EdifactDeserialize for segment or message structs.
EdifactSerializederive
Derive edifact_rs::EdifactSerialize for segment or message structs.