# hl7-net
[](https://crates.io/crates/hl7-net)
[](https://docs.rs/hl7-net)
[](LICENSE.txt)
A lightweight **HL7 v2** message parser and writer for Rust.
`hl7-net` is an idiomatic Rust port of the
[Efferent HL7-V2](https://github.com/Efferent-Health/HL7-V2) .NET library. It keeps
the original library's HL7 semantics — delimiter handling, escaping, "present but
null" values, MLLP framing and the round-trip self-check — while reworking the API
around Rust conventions (`snake_case`, `Result`-based error handling, and a pure-data
element tree).
## Features
- Parse HL7 v2 messages into a `Segment` / `Field` / `Component` / `SubComponent` tree.
- Read and write values by path (`PID.5.1`, `MSH.9.3`, `PID(2).3.1`).
- Full HL7 escaping/unescaping (`\F\`, `\S\`, `\R\`, `\E\`, `\T\`, `\Xnn\` hex, and
the `<B>`/`</B>`/`<BR>` formatting sequences).
- "Present but null" (`""`) values modelled as `Option<String>`.
- Generate ACK / NACK responses.
- MLLP framing helpers (`<VT> … <FS><CR>`) for stream transport.
- HL7 date/time parsing and formatting via [`jiff`](https://docs.rs/jiff).
- A parse-time round-trip check: a message is only considered valid if re-serializing
it reproduces the (hex-normalized) original.
## Installation
Add the crate with Cargo:
```sh
cargo add hl7-net
```
Or add it to `Cargo.toml` manually:
```toml
[dependencies]
hl7-net = "0.1"
```
The minimum supported Rust version (MSRV) is **1.88** (Rust 2024 edition).
## Usage
### Parsing a message and reading values
```rust
use hl7_net::Message;
// `parse` returns Ok(true) when the message round-trips cleanly.
assert!(message.parse(false).unwrap());
// Read by path: segment.field.component.subcomponent (all 1-based).
assert_eq!(message.get_value("MSH.9.1").unwrap(), "ADT");
assert_eq!(message.get_value("PID.5.1").unwrap(), "EVERYMAN");
// Message-level metadata extracted from MSH.
assert_eq!(message.version, "2.5");
assert_eq!(message.message_control_id, "MSGID");
```
### Updating values
```rust
use hl7_net::Message;
let mut message = Message::parse_str(
"MSH|^~\\&|App|Fac|App2|Fac2|20200101000000||ADT^A01^ADT_A01|MSGID|P|2.5\r\
PID|1||PATID1234^5^M11||EVERYMAN^ADAM^A^III||19610615|M\r",
false,
).unwrap();
message.set_value("PID.5.1", "SMITH").unwrap();
assert_eq!(message.get_value("PID.5.1").unwrap(), "SMITH");
// Serialize back to HL7 text.
let out = message.serialize().unwrap();
assert!(out.contains("SMITH^ADAM"));
```
### Acknowledgements and MLLP framing
```rust
use hl7_net::Message;
let message = Message::parse_str(
"MSH|^~\\&|App|Fac|App2|Fac2|20200101000000||ADT^A01^ADT_A01|MSGID|P|2.5\r",
false,
).unwrap();
assert_eq!(ack.get_value("MSA.1").unwrap(), "AA");
// Wrap a message in an MLLP frame for transport over a socket.
let framed: Vec<u8> = message.get_mllp().unwrap();
assert_eq!(framed[0], 0x0B); // <VT>
```
### Encoding helpers and date handling
```rust
use hl7_net::HL7Encoding;
use hl7_net::helper;
let enc = HL7Encoding::default();
let encoded = enc.encode("Smith & Sons");
assert_eq!(enc.decode(&encoded), "Smith & Sons");
// Parse an HL7 timestamp (with optional fraction and timezone offset).
let dt = helper::parse_date_time("20200101120000.5+0100").unwrap();
assert_eq!(dt.to_utc().unwrap().to_string(), "2020-01-01T11:00:00.5Z");
```
## API overview
| `Message` | A parsed message; metadata plus the segment tree and value access |
| `Segment` | A named segment (`MSH`, `PID`, …) holding a list of fields |
| `Field` | A field; either componentized or carrying repetitions |
| `Component` | A component made of one or more subcomponents |
| `SubComponent` | The smallest data unit |
| `HL7Encoding` | Delimiter set and the escape/unescape routines |
| `Hl7Error` | Error type carrying a message and an optional category code |
| `helper` | Date/time, message splitting and MLLP framing utilities |
The element tree is **pure data**: `HL7Encoding` is threaded into the parse,
serialize and value methods (e.g. `field.value(&enc)`) rather than stored on each
node, which keeps the tree borrow-friendly and cheap to clone.
## Building from source
```sh
git clone https://github.com/Tirax-Tech/hl7-net.git
cd hl7-net
cargo build
cargo test # unit tests, helper tests and doc tests
cargo clippy --all-targets
```
## License
Licensed under the [MIT License](LICENSE.txt).
This project is a derivative work of the
[Efferent HL7-V2](https://github.com/Efferent-Health/HL7-V2) .NET library, which is
also MIT licensed; the original copyright notice is retained in `LICENSE.txt`.