Crates

hl7-2-from-json-into-er7

Typed JSON → ER7

Format conversions v0.4.2 CLI: hl7-2-from-json-into-er7 Specified

Install cargo add hl7-2-from-json-into-er7
Rust path hl7_2_from_json_into_er7
Dependencies er7
Links crates.io docs.rs source spec

What it is

Convert HL7 v2.5 messages from the typed JSON representation that hl7-2-from-er7-into-json produces, back to the traditional pipe-delimited ER7 encoding, as a Rust library and command-line tool.

Why it needs no dictionary

What it produces

A JSON fragment such as:

json
{
  "PID.1": "1",
  "PID.3": { "CX.1": "241900" },
  "PID.5": { "XPN.1": { "FN.1": "TEST" }, "XPN.2": "FOUAZ" }
}

converts back to:

er7
PID|1||241900||TEST^FOUAZ

Command line

sh
# From a file to stdout
hl7-2-from-json-into-er7 samples/orm_o01.json

# From stdin, to a file
cat samples/oru_r01.json | hl7-2-from-json-into-er7 -o out.hl7

# Choose the segment terminator
hl7-2-from-json-into-er7 --terminator crlf samples/orm_o01.json

Message-structure group keys ("ORM_O01.PATIENT", "ORU_R01.ORDER_OBSERVATION", …) are flattened automatically, and a repeating field, segment, or group's JSON array un-arrays back into its repetitions or repeated segments — grouped and --flat, single-occurrence and repeated, all reconstruct the same message.

Library

rust
let json = r#"{
  "ORM_O01": {
    "MSH": { "MSH.1": "|", "MSH.2": "^~\\&", "MSH.9": {"MSG.1": "ORM", "MSG.2": "O01"} },
    "ORM_O01.PATIENT": {
      "PID": { "PID.5": { "XPN.1": {"FN.1": "TEST"}, "XPN.2": "FOUAZ" } }
    }
  }
}"#;

let er7 = hl7_2_from_json_into_er7::convert(json)?;
rust
use hl7_2_from_json_into_er7::parse;

let message = parse(json)?;
assert_eq!(message.query("PID-5.1")?.as_deref(), Some("TEST"));

convert, convert_with_options, and parse return Result<_, Hl7Error>; an Err only ever means the input is not well-formed JSON, is not shaped like a converted message (a single-key object over an object of segments), or the message has no usable MSH/FHS/BHS header.

What it does

  • A minimal, dependency-free JSON reader: the full RFC 8259 grammar including \uXXXX surrogate pairs, with numbers and booleans tolerated (coerced to text) even though the forward crate never emits them.
  • Position-based reconstruction, no data-type dictionary — see above.
  • Group flattening and array un-nesting: group keys are recognized by their dotted name and flattened back into a plain segment sequence, and a JSON array un-arrays into repeated occurrences. No message-structure grammar is needed in this direction.
  • Delimiter recovery: the header's .1 and .2 fields are reassembled into a synthetic header line and handed to er7::Separators::from_header.
  • Faithful re-escaping: decoded leaf text is retokenized against er7's own escape-sequence vocabulary, so delimiter characters are re-escaped while formatting sequences the forward crate never decoded (\.br\, \H\, …) are written back exactly as they were.
  • HL7 null: JSON null reconstructs as the explicit null "" at that position.

Limitations

  • A field repetition that was present but entirely blank (not the explicit null) is dropped by the forward crate's own encoding and cannot be recovered here.
  • One JSON document converts to one ER7 message; there is no batch-file convention on the JSON side to split.
  • A segment name that repeated non-adjacently in the original message was already collapsed by the forward crate — a JSON object cannot carry the same key twice — so its original sequence cannot be restored here either.

See spec/index.md §5 for the full list.