fhir-types 0.1.102

Generated per-version FHIR types and terminology operation contracts
Documentation

fhir-types

Per-version FHIR types and terminology operation contracts.

Generated Rust types for the FHIR R4 (4.0.1), R4B (4.3.0), R5 (5.0.0), and R6 (6.0.0-ballot5) terminology surface: CodeSystem, ValueSet, ConceptMap, Parameters, OperationOutcome, CapabilityStatement, TerminologyCapabilities, Bundle, the datatypes and primitives they reach, a JSON codec, and typed request and response contracts for $lookup, $validate-code, $expand, $subsumes, and $translate per version, each with a runtime descriptor of the declared parameter set. The resources feature widens the same tree to every concrete resource each package defines, with the complete closure of the datatypes those resources reference.

Features

One tree holds every type the generator emits, and the features select inside it. The default set is what a dependant gets with no feature list.

Feature What it enables Default
r4 the FHIR R4 (4.0.1) module yes
r4b the FHIR R4B (4.3.0) module yes
r5 the FHIR R5 (5.0.0) module yes
r6 the FHIR R6 (6.0.0-ballot5) module yes
terminology the terminology root set, the closure of the types it references, and the operation contracts yes
resources every concrete resource each package defines, with its complete closure; enables terminology no

A version module carries only the types the enabled root set selects, so default-features = false with r4 and terminology builds the R4 terminology surface alone. Resource holds one variant per resource the enabled features select, and UnknownResource carries any other resource's JSON body unchanged.

Every file is generated by fhir-codegen from the vendored HL7 packages and marked // @generated. To change the output, change the generator and regenerate; the crate is never hand-edited. The terminology ecosystem overlay (the HL7 terminology ecosystem IG requirements) is applied at generation and marked per parameter.

The element table

Each version module carries schema::SCHEMAS, the elements of every type it emits in definition order. Per element it holds the ElementDefinition path, min, max, the type codes the definition lists, the contentReference target, and the kind the XML codec reads. Schemas::element resolves a dotted element path through complex types, backbone elements and content references, and answers on a choice element's base path and on each expanded form the JSON representation gives it; Schemas::type_of gives the type a path resolves to.

use fhir_types::r4::schema::SCHEMAS;

let (owner, element) = SCHEMAS
    .element("Parameters.parameter.valueQuantity")
    .expect("a defined element");
assert_eq!(owner.path, "Parameters.parameter");
assert_eq!(element.path, "Parameters.parameter.value[x]");
assert_eq!((element.min, element.max), (0, Some(1)));
assert_eq!(
    SCHEMAS
        .type_of("Parameters.parameter.valueQuantity")
        .map(|schema| schema.name),
    Some("Quantity"),
);

A type the enabled features leave out is absent from the table, so a path into it resolves to None.

JSON and decimal precision

The codec reads and writes FHIR JSON through its own document model, fhir_types::codec::Value, which holds a number in the text the document carried. FHIR says "Do not use an IEEE type floating point type, instead use something that works like a true decimal" (https://hl7.org/fhir/R4B/datatypes.html#decimal), so 1.10 keeps its trailing zero and a decimal past f64 precision keeps its digits, through the Serialize impls and through Json::to_json alike.

That costs a dependent nothing. The crate turns on no serde_json feature that changes how numbers deserialize, so your own types keep reading and writing the JSON they always did. Reading a document uses serde_json's raw value, so the Deserialize impls read serde_json's format.

Converting to and from serde_json::Value

A decimal is never silently altered, so the conversion out is fallible. Value::into_serde_json and Value::to_serde_json hand the document to serde_json only when every number comes back in the text the document carried; a number serde_json would write differently, or cannot hold at all, is a ValueConversionError naming the element path (Observation.valueQuantity.value), the lexical form and what serde_json writes. With arbitrary_precision on your side every form converts; without it, whole numbers and the decimals f64 writes back convert and 1.50 is refused.

Value::from_serde_json is the other direction and cannot fail. It takes the number in the text serde_json holds, which is the document's own form under arbitrary_precision and the f64 rendering of it otherwise, so read a document whose decimals must stay exact through this crate's decoder (serde_json::from_str::<fhir_types::codec::Value>) rather than through serde_json::Value.

Where it sits

fhir-types is generated in FerroBRIDGE, a pure-Rust bridge between openEHR and HL7 FHIR and the OMOP Common Data Model. The crate is published so other projects can reuse it; the API is pre-1.0 and moves with the FerroBRIDGE release train. Documentation: https://docs.rs/fhir-types.

Licence

Apache License, Version 2.0 (LICENSE). This is the one first-party crate the workspace publishes under Apache 2.0 rather than its Business Source License 1.1, so any Rust project can depend on it without a licence conversation. Clinical terminology content (SNOMED CT, LOINC, RxNorm, ICD, the Dutch national code systems) is licensed by its publisher and is never part of this crate.