FHIR R5 for Rust
A Rust implementation of the HL7 FHIR® Release 5 (R5) data model, plus a code generator that produces it from the official FHIR specification JSON files.
Fast Healthcare Interoperability Resources (FHIR, pronounced "fire") is the HL7
standard for exchanging electronic health records. This crate lets you build,
parse, validate, and round-trip FHIR resources in idiomatic Rust with serde.
Status: work in progress. The R5 data model (resources, datatypes, primitives, code systems, validation) is implemented and green; APIs may still change before 1.0.
FHIR® is a registered trademark of Health Level Seven International. This crate is not affiliated with or endorsed by HL7.
Features
- 158 R5 resources (Patient, Observation, Encounter, …) as Rust structs,
each round-tripping to and from canonical FHIR JSON via
serde. - ~50 complex datatypes (Period, HumanName, CodeableConcept, …) and 21
primitive newtypes (
Code,Id,DateTime, …) that serialize transparently. - 400+ code systems as type-safe enums that serialize to their canonical FHIR code strings.
- A polymorphic
Resourceenum, tagged byresourceType, for reading a resource whose type you do not know ahead of time. - Lightweight validation via a
Validatetrait and#[derive(Validate)]that walks every field recursively. - A code generator that reads the bundled FHIR R5 spec JSON and emits Rust.
Installation
[]
= "0.1"
= "1" # or any other serde data format
Quick start
Build a Patient, serialize to canonical FHIR JSON, and parse it back:
use Patient;
use ;
let patient = Patient ;
let json = to_string_pretty.unwrap;
let parsed: Patient = from_str.unwrap;
assert_eq!;
How the model maps to Rust
Everything derives serde::Serialize and serde::Deserialize, so you work
through serde_json (or any serde format).
-
Primitives are transparent newtypes.
Code("final")serializes to the JSON string"final"— no wrapper object. (integer64is the FHIR-mandated exception: it serializes as a JSON string.) -
Element cardinality maps directly:
FHIR cardinality Rust type 0..1Option<T>1..1T0..*Option<Vec<T>>1..*Vec<T> -
value[x]choice elements are flattened into one field per allowed type, namedvalue_<type>(e.g.Observationhasvalue_quantity,value_string,value_boolean, …); set exactly one. -
Nested backbone elements become nested structs named
<Parent><Field>(e.g.PatientContact,BundleEntry). -
Unset optional fields are omitted from the JSON (
skip_serializing_none).
Validation
Validate reports every problem as a ValidationIssue { path, message }.
Primitive types check their FHIR regex constraints; #[derive(Validate)] makes
complex types and resources validate recursively, prefixing each nested issue's
path with the field name.
use Id;
use Validate;
assert!;
assert!;
Code systems
use AdministrativeGender;
let gender = Female;
assert_eq!;
Reading a resource of unknown type
use Resource;
let json = json!;
match from_value.unwrap
Runnable examples
Programs in the examples/ directory demonstrate common tasks:
Crate layout
src/
lib.rs Crate root and guide (see `cargo doc --open`)
r5/
resources/ 158 resource structs + the polymorphic `Resource` enum
types/ ~50 complex datatypes + 21 primitive newtypes
codes.rs FHIR CodeSystems as enums
validate.rs `Validate` trait + primitive constraints
parse/ Code generator that reads the spec JSON
fhir-derive-macros/ Proc-macro crate providing `#[derive(Validate)]`
doc/ Bundled FHIR R5 specification JSON files
examples/ Runnable example programs
Documentation
Build and open the full API documentation, including the crate guide and every resource/datatype:
The code generator
The types under src/r5/types and src/r5/resources are derived from the
official FHIR R5 specification JSON in
doc/fhir-specifications/r5/fhir-definitions-json/ (exposed at runtime as
fhir::DEFINITIONS_DIR). The generator lives under src/r5/parse; the binary
in src/main.rs drives it. See AGENTS.md and
spec/ for the generator's design and conventions.
FHIR specification reference
The remainder of this document is background reference on the FHIR R5 specification files the generator consumes. It is useful when working on the generator itself.
Datatype categories
FHIR R5 datatypes live in profiles-types.json, which distinguishes primitive
types (lowercase names) from complex types (uppercase names).
Primitive types: base64Binary, boolean, canonical, code, date,
dateTime, decimal, id, instant, integer, integer64, markdown,
oid, positiveInt, string, time, unsignedInt, uri, url, uuid.
General-purpose complex types: Address, Age, Annotation, Attachment, CodeableConcept, Coding, ContactPoint, Count, Distance, Duration, HumanName, Identifier, Money, MoneyQuantity, Period, Quantity, Range, Ratio, RatioRange, SampledData, Signature, SimpleQuantity, Timing.
Metadata complex types: Availability, ContactDetail, Contributor, DataRequirement, Expression, ExtendedContactDetail, MonetaryComponent, ParameterDefinition, RelatedArtifact, TriggerDefinition, UsageContext, VirtualServiceDetail.
Special-purpose complex types: BackboneType, CodeableReference, Dosage, ElementDefinition, Extension, Meta, Narrative, Reference, xhtml.
You can list the ids straight from the spec with jq:
<profiles-types.json
<profiles-types.json
Element extension URLs
Any element defined in any version of FHIR is automatically assigned an extension URL that uniquely identifies it:
http://hl7.org/fhir/[version]/StructureDefinition/extension-[Path]
Snapshot view versus differential view
A FHIR profile offers two views of a profiled resource:
- Snapshot — the complete, final structure after applying all changes from the differential to the base resource. Self-contained; useful when you do not have the base resource at hand.
- Differential — only the differences (added, modified, or removed elements) the profile introduces relative to its base. Useful for understanding what a profile customizes.
FHIR documentation links
- Datatypes: https://build.fhir.org/datatypes.html
- JSON representation: https://build.fhir.org/json.html
- UML: https://build.fhir.org/uml.html
- References: https://build.fhir.org/references.html
- Extensibility: https://build.fhir.org/extensibility.html
- Narrative: https://build.fhir.org/narrative.html
- Resource: https://build.fhir.org/resource.html
- Versions / standards process: https://build.fhir.org/versions.html#std-process
License
Licensed under any of:
- MIT
- Apache License 2.0
- BSD 3-Clause
- GPL 2.0 only
- GPL 3.0 only
at your option.