Skip to main content

Crate serde_hl7_v3

Crate serde_hl7_v3 

Source
Expand description

§serde-hl7-v3

Serde support for hl7_3, the HL7® v3 foundation crate: wrap a parsed hl7_3::Message in Message, a RIM class in Act or Entity, a data type in Ii or Cd, or a raw XML element in Element, and it can flow through serde_json, serde_yaml, bincode, or any other Serde data format — for storing a decoded interaction in a document database, logging it as structured JSON, returning it from a web API, or testing against a literal.

hl7_3 has one runtime dependency, the XML reader it parses through, and no Serde support of its own, deliberately: adding serde there would cost every user of hl7-3 a dependency they may not want. This crate is the bridge instead — two dependencies, serde and hl7-3, and nothing else. Every impl is written by hand against the low-level Serializer/Deserializer/Visitor traits, following the pattern serde’s own documentation walks through for a manual implementation — no #[derive(Serialize)] anywhere, because the types wrapped here are foreign and the shapes below are chosen, not derived.

Most callers get this crate through the serde-hl7 umbrella, which re-exports it as serde_hl7::v3, the same way hl7 re-exports hl7-3 as hl7::v3.

§Trademarks

HL7®, and FHIR® are the registered trademarks of Health Level Seven International and their use of these trademarks does not constitute an endorsement by HL7.

§Example

use serde_hl7_v3::Message;

let xml = r#"
<QUQI_IN000001UV01 xmlns="urn:hl7-org:v3">
  <id root="2.16.840.1.113883.19.5" extension="MSG00001"/>
  <interactionId root="2.16.840.1.113883.1.6" extension="QUQI_IN000001UV01"/>
  <controlActProcess classCode="CACT" moodCode="EVN">
    <code code="QUQI_TE000001UV01"/>
    <subject><observation classCode="OBS" moodCode="EVN"/></subject>
  </controlActProcess>
</QUQI_IN000001UV01>"#;

let message = Message::parse(xml)?;

// Out to JSON, and back — this crate never mentions JSON itself; any
// Serde format works the same way.
let json = serde_json::to_string(&message)?;
let back: Message = serde_json::from_str(&json)?;

assert_eq!(back, message);
assert_eq!(back.interaction_id.as_ref().unwrap().extension.as_deref(), Some("QUQI_IN000001UV01"));

§The shape each type serializes as

Every type is an object whose keys are the hl7-3 field names in lowerCamelCase — which, for every field that corresponds to an HL7 v3 XML attribute or element, is that attribute’s or element’s own name: classCode, moodCode, codeSystem, effectiveTime, interactionId. An Option field serializes as null when absent; a Vec field as an array, [] when empty.

hl7-3 typeWrapperKeys
hl7_3::MessageMessageid, creationTime, interactionId, sender, receiver, controlAct
hl7_3::ControlActControlActclassCode, moodCode, code, domain
hl7_3::xml::ElementElementname, attributes (an object), text, children
hl7_3::IiIiroot, extension
hl7_3::CdCdcode, codeSystem, displayName
hl7_3::IvlIvlvalue, low, high
hl7_3::PqPqvalue, unit
hl7_3::EdEdmediaType, representation, text
hl7_3::NullFlavorNullFlavora bare string: the code, "NI", "UNK", …
hl7_3::rim::ActActclassCode, moodCode, id, code, statusCode, effectiveTime, text
hl7_3::rim::EntityEntityclassCode, determinerCode, id, code, name
hl7_3::rim::RoleRoleclassCode, id, code, statusCode, effectiveTime
hl7_3::rim::ParticipationParticipationtypeCode, time, functionCode
hl7_3::rim::ActRelationshipActRelationshiptypeCode, inversionInd
hl7_3::rim::RoleLinkRoleLinktypeCode

Deserializing any object ignores a key it does not recognize, by default. A caller who wants a typo in a hand-written JSON fixture reported instead deserializes into Strict<T>, which rejects an unknown key — at the top level or nested anywhere beneath — rather than ignoring it.

§What round-trips

A value through any Serde format and back is equal to the value that went in — every field of every type here is public, so nothing is lost in either direction. What this crate does not promise is XML: hl7-3 reads a message into its three-level envelope and keeps the payload as a raw Element, and it has no XML writer, so there is no “back to the original document” here to guarantee. The Element tree itself round-trips exactly, attributes and children included.

§What is deliberately not here

This crate adds exactly one thing to hl7_3: Serde support for its existing public types. It does not add a wire format (serde_json is a dev-dependency only), an XML writer, or Serde support for the struct-mode trait hl7_3::FromElement — a caller’s own struct is theirs to derive Serde for.

§Documentation

spec/index.md in the repository is this crate’s specification — what each wrapper type must serialize as and why. Runnable programs are in examples/.

Re-exports§

pub use hl7_3;

Structs§

Act
A Serde-enabled hl7_3::rim::Act.
ActRelationship
A Serde-enabled hl7_3::rim::ActRelationship.
Cd
A Serde-enabled hl7_3::Cd: a coded value.
ControlAct
A Serde-enabled hl7_3::ControlAct: the control act wrapper, and the domain payload it carries.
Ed
A Serde-enabled hl7_3::Ed: encapsulated data.
Element
A Serde-enabled hl7_3::xml::Element: the raw XML tree hl7-3 reads through, and keeps for the parts of a message it does not model — hl7_3::Message::sender, hl7_3::Message::receiver, and the domain payload under hl7_3::ControlAct::domain.
Entity
A Serde-enabled hl7_3::rim::Entity.
Ii
A Serde-enabled hl7_3::Ii: an instance identifier.
Ivl
A Serde-enabled hl7_3::Ivl: an interval, as raw bound text.
Message
A Serde-enabled hl7_3::Message — the crate’s main entry point: the transport wrapper, with the control act wrapper and the domain payload nested inside it.
NullFlavor
A Serde-enabled hl7_3::NullFlavor.
Participation
A Serde-enabled hl7_3::rim::Participation.
Pq
A Serde-enabled hl7_3::Pq: a physical quantity, as raw text.
Role
A Serde-enabled hl7_3::rim::Role.
RoleLink
A Serde-enabled hl7_3::rim::RoleLink.
Strict
Deserialize T strictly: an unrecognized field is a serde::de::Error instead of being ignored.