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 fromedifact-rs-derive.diagnostics(disabled by default): enables rich diagnostic output viamiette. When enabled, errors implementmiette::Diagnosticfor 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 configurationThis 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 (
E003on failure). - Release characters must escape exactly one following byte.
A trailing
?at end-of-input is rejected (E018). - 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:
- Use your async runtime’s read utilities to read the entire message into a
Vec<u8>(e.g.tokio::io::AsyncReadExt::read_to_end). - 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 envelope::validate_envelope;pub use error::EdifactError;pub use error::IoError;pub use error::ValidationIssue;pub use error::ValidationReport;pub use error::ValidationSeverity;pub use model::BorrowedElement;pub use model::BorrowedSegment;pub use model::Element;pub use model::OwnedElement;pub use model::OwnedSegment;pub use model::Segment;pub use model::Span;pub use parser::Parser;pub use parser::ReaderConfig;pub use parser::from_bufread;pub use parser::from_bufread_stream;pub use parser::from_bufread_stream_with_config;pub use parser::from_reader_with_config;pub use tokenizer::ServiceStringAdvice;pub use tokenizer::Tokenizer;pub use validator::ProfileRule;pub use validator::ProfileRulePack;pub use validator::ValidationContext;pub use validator::ValidationContextBuilder;pub use validator::ValidationLayer;pub use validator::Validator;pub use validator::validate_each;pub use writer::Writer;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::composite_element;pub use de::contiguous_groups_by_qualifier;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::element_str;pub use de::find_qualified_segment;pub use de::find_qualified_segment_owned;pub use de::find_segment;pub use de::find_segment_owned;pub use de::find_segment_typed;pub use de::find_segments_iter;pub use de::find_segments_typed;pub use de::get_components_iter;pub use de::groups_are_contiguous_by_qualifier;pub use de::message_windows_bytes;pub use de::message_windows_from_reader;pub use de::optional_component;pub use de::optional_element;pub use de::qualifier_matches_pattern;pub use de::required_component;pub use de::required_element;pub use event::EdifactEvent;pub use event::EventEmitter;pub use event::OwnedEdifactEvent;pub use event::VecEmitter;pub use event::WriterEmitter;pub use ser::EdifactCompositeSerialize;pub use ser::EdifactSerialize;pub use ser::to_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.
- envelope
- EDIFACT envelope validation (Story 2.4).
- error
- Error types and validation reporting primitives.
- event
- Event model for EDIFACT (de)serialization.
- model
- Core zero-copy and owned EDIFACT data model types.
- parser
- Streaming EDIFACT parser — wraps a
Tokenizerand assemblesSegments. - ser
- Custom serialization trait for EDIFACT.
- tokenizer
- EDIFACT tokenizer — splits raw bytes into typed tokens.
- validator
- Validation pipeline for structural and semantic EDIFACT checks.
- writer
- EDIFACT writer — serializes
Segments to wire format.
Structs§
- From
Bytes Iter - Iterator returned by
from_bytes. - From
Reader Iter - Iterator returned by
from_reader_iter.
Functions§
- from_
bytes - Parse
inputbytes into an iterator ofSegments. - from_
reader - Parse a reader into owned segments.
- from_
reader_ iter - Parse a reader into owned segments as a streaming iterator.
- to_
bytes - Serialize
segmentsto an ownedVec<u8>. - to_
writer - Serialize
segmentsto anstd::io::Writeimplementation.
Derive Macros§
- Edifact
Deserialize derive - Derive
edifact_rs::EdifactDeserializefor segment or message structs. - Edifact
Serialize derive - Derive
edifact_rs::EdifactSerializefor segment or message structs.