Expand description
Parse, navigate, validate, modify, and write HL7 v2 messages, in three modes that share one set of internals.
HL7 v2 is the format most healthcare data still moves in, and most of
the difficulty in reading it is not the syntax — that is pipes and
carets, and the er7 crate this one is built on already handles it —
but knowing what the pipes and carets mean in the release the sender
speaks. This crate owns that knowledge: the per-release data-type
tables, the message structures, and the three ways to apply them.
Published standalone as hl7-2; most users get it through the hl7
umbrella crate instead, which re-exports this crate as hl7::v2:
[dependencies]
hl7 = "0.1"§Three modes
Generic — for the vendor whose messages you have never seen and need to explore. Parse anything into a navigable tree; nothing is rejected and nothing is dropped.
let message = hl7_2::parse("MSH|^~\\&|LAB||EPIC||20240101||ORU^R01|1|P|2.5\r\
PID|1||241900||SMITH^JOHN\r\
OBR|1||X|GLU\r\
OBX|1|NM|GLU^Glucose||7.4|mmol/L")?;
let tree = message.tree();
assert_eq!(tree.name(), "ORU_R01");
assert_eq!(tree.find("XPN.1").unwrap().text(), "SMITH");
assert_eq!(message.get("OBX-5")?.as_deref(), Some("7.4"));Schema-based — for the vendor whose quirks you have learned but whose format is not frozen. Write the shape as JSON, load it at runtime, and adding a field needs no recompile.
use std::sync::Arc;
let dictionary = hl7_2::Dictionary::from_json(r#"{
"inherits": "2.5",
"segments": { "ZPD": ["ST", "XPN"] }
}"#, "acme")?;
let options = hl7_2::Options::new().with_dictionary(Arc::new(dictionary));
let message = hl7_2::parse_with_options(
"MSH|^~\\&|ACME||||1||ADT^A01|1|P|2.5\rZPD|7|SMITH^JOHN",
&options,
)?;
// The vendor's own segment now reads like any standard one.
assert_eq!(message.tree().find("XPN.2").unwrap().text(), "JOHN");Struct-based — for the stable, long-lived feed where you want the
compiler’s help. See typed for the derive macros, and for the Raw
field that keeps the generic escape hatch open on the same object.
§What this crate is, and is not
It is the HL7 v2 dictionary layer: releases 2.1 through 2.9, data types,
message structures, three modes, mutation, and validation. It is not the
ER7 encoding layer — parsing, delimiters, escape sequences, and
byte-for-byte rendering all belong to er7, which is this crate’s
only runtime dependency and has none of its own. It is also not a
transport: MLLP, files, and queues are the caller’s business.
spec/index.md in the repository is the normative specification of
everything above; where this documentation and that document disagree,
that document is right.
Re-exports§
pub use builder::Builder;pub use dictionary::Dictionary;pub use generic::Node;pub use message::Message;pub use typed::FromHl7;pub use typed::FromHl7Text;pub use typed::FromHl7Value;pub use typed::Raw;pub use typed::ToHl7;pub use typed::ToHl7Text;pub use typed::ToHl7Value;pub use validate::Diagnostic;pub use validate::Severity;pub use version::Version;pub use er7;
Modules§
- builder
- Building a message from nothing.
- dictionary
- The HL7 v2 dictionary: what a segment’s fields mean, what a composite data type is made of, and how a message’s segments group.
- generic
- Generic mode: parse anything into a navigable tree.
- json
- A small hand-written JSON reader, used to load dictionaries.
- message
- The parsed message: what release it speaks, what structure it is, and how to read, change, and write it back.
- structure
- Matching a message’s segments against an abstract message structure.
- typed
- Struct mode: compile-time types for the feed that does not change.
- validate
- Checking a message against the dictionary it claims to speak.
- version
- Which release of HL7 v2 a message speaks, and which dictionary that selects.
Structs§
- Options
- How to read a message: which release, which dictionary, and whether validation failures are fatal.
Enums§
- Error
- What can go wrong.
Functions§
- parse
- Parse one message, reading the release from MSH-12.
- parse_
with_ options - Parse one message under
options. - split_
messages - Split input that may hold several messages, or an HL7 batch file, into individual messages — one per MSH segment. Batch envelope segments (FHS, BHS, BTS, FTS) are dropped.