FHIR Code Generation Library
A Rust library for generating type-safe Rust code from FHIR StructureDefinition JSON files, with support for FHIR package downloading and management.
Overview
The rh-codegen crate provides comprehensive functionality for:
- FHIR Type Generation: Parse FHIR StructureDefinition JSON files and generate corresponding Rust struct definitions
- Type Safety: Generate type-safe enums for required value set bindings
- Metadata Generation: Generate compile-time metadata for type resolution and FHIRPath evaluation
- Package Management: Download FHIR packages from npm-style registries
- Batch Processing: Process entire directories of FHIR definitions
- Automatic Extraction: Extract and process StructureDefinitions from package tarballs
- Configuration: Flexible configuration for type mappings and output settings
Crate Generation
When generating a crate, the following idiomatic Rust layout will be created:
hl7_fhir_r4_core/
├── Cargo.toml
├── src/
│ ├── lib.rs
│ ├── macros.rs
│ ├── metadata.rs
│ ├── bindings/
│ │ ├── mod.rs
│ │ ├── observation_status.rs
│ │ ├── allergy_category.rs
│ │ ├── encounter_class.rs
│ │ └── ...
│ ├── datatypes/
│ │ ├── mod.rs
│ │ ├── narrative.rs
│ │ ├── extension.rs
│ │ ├── coding.rs
│ │ ├── codeable_concept.rs
│ │ └── ...
│ ├── extensions/
│ │ ├── mod.rs
│ │ └── ...
│ ├── primitives/
│ │ ├── mod.rs
│ │ ├── string.rs
│ │ ├── boolean.rs
│ │ ├── date_time.rs
│ │ └── ...
│ ├── profiles/
│ │ ├── mod.rs
│ │ └── ...
│ ├── resources/
│ │ ├── mod.rs
│ │ ├── observation.rs
│ │ ├── patient.rs
│ │ ├── bundle.rs
│ │ └── ...
│ └── traits/
│ ├── mod.rs
│ ├── resource.rs
│ ├── domain_resource.rs
│ ├── has_extensions.rs
│ ├── has_coding.rs
│ └── ...
Quick Start
Add to your Cargo.toml:
[]
= { = "../path/to/rh-codegen" }
# Or if using from the workspace root:
# rh-codegen = { path = "crates/rh-codegen" }
Basic Usage
use ;
use Path;
Metadata Generation
The code generator produces compile-time metadata for FHIR types, enabling runtime type resolution and validation. This metadata is used by the FHIRPath evaluator to return correctly typed values.
Metadata Module
The generated metadata.rs module contains:
- FhirPrimitiveType enum: Defines all FHIR primitive types (Boolean, Integer, String, Date, DateTime, etc.)
- FhirFieldType enum: Categorizes fields as Primitive, Complex, Reference, or BackboneElement
- FieldInfo struct: Contains field metadata including type, cardinality (min/max), and choice type flag
- Type maps: Compile-time maps (using
phf) for efficient field lookup
Example Metadata Usage
use ;
// Look up field metadata at runtime
if let Some = get_field_info
// Check cardinality
if let Some = get_field_info
This metadata enables FHIRPath expressions to return properly typed values instead of generic strings. For example, Patient.birthDate returns a Date type rather than a String.
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
output_dir |
String |
"src/generated" |
Default output directory for generated files |
module_name |
String |
"fhir_types" |
Module name for generated types |
with_serde |
bool |
true |
Generate serde Serialize/Deserialize derives |
with_docs |
bool |
true |
Include documentation comments |
type_mappings |
Map<String, String> |
See below | Custom FHIR type to Rust type mappings |
Default Type Mappings
| FHIR Type | Rust Type | Notes |
|---|---|---|
string |
String |
Basic string type |
integer |
i32 |
Signed 32-bit integer |
boolean |
bool |
Boolean true/false |
decimal |
f64 |
64-bit floating point |
uri, url, canonical |
String |
Could use custom URI types |
date, dateTime, instant |
String |
Could use chrono types |
code |
String or Enum |
Becomes enum for required value set bindings |
id, oid |
String |
Identifier types |
base64Binary |
String |
Could use Vec<u8> |
markdown |
String |
Markdown content |
Generated Code Examples
Basic Resource Generation
From a FHIR Patient StructureDefinition:
use ;
/// FHIR Patient resource
Type-Safe Enums for Value Sets
For code fields with required value set bindings:
/// The gender of a person used for administrative purposes.
Choice Types (value[x])
FHIR choice types are expanded into multiple typed fields:
Usage Examples
Creating Resources
use serde_json;
// Create a new patient
let patient = Patient ;
// Serialize to JSON
let json = to_string_pretty?;
Parsing Resources
use serde_json;
let json_data = r#"
{
"resourceType": "Patient",
"id": "example",
"name": [{
"family": "Smith",
"given": ["Jane"]
}],
"birthDate": "1985-06-23",
"gender": "female"
}
"#;
let patient: Patient = from_str?;
println!;
Type-Safe Pattern Matching
match patient.gender
Generated Code Features
Primitive Field Extensions
For FHIR primitive fields that can have extensions, the generator creates companion extension fields:
The Element type allows attaching extensions to primitive values while maintaining FHIR compliance.
FHIR Package Management
Registry Support
The library supports downloading FHIR packages from npm-style registries:
- FHIR Package Registry: https://packages.fhir.org (default)
- Custom npm-style registries: Any registry following npm package conventions
- Private registries: With authentication token support
Download Process
- Registry Interaction: Fetches package metadata from npm-style registries using HTTP
- Package Download: Downloads the package as a compressed tarball (.tgz)
- Extraction: Extracts JSON files from the tarball
- Processing: Identifies StructureDefinition files and generates Rust types
- Code Generation: Uses the same generation pipeline as file-based processing
Example: Package Download and Processing
use ;
use ;
use Path;
async
Library Architecture
The crate is organized into modular components with specialized generators:
Core Modules
-
generator.rs: Main orchestrating code generatorCodeGenerator: Coordinates specialized sub-generators with built-in cachingCodegenConfig: Configuration for type generation- Type and enum caching to avoid regenerating identical structures
-
generators/: Specialized generation modulesTokenGenerator: Core token generation using proc-macro2 and quoteStructGenerator: FHIR struct to Rust struct generationTraitGenerator: FHIR resource trait generationEnumGenerator: Value set enum generationFieldGenerator: Struct field generation with type mappingCrateGenerator: Full crate structure generationFileGenerator: File organization and writingNameGenerator: Rust-idiomatic naming conventionsTypeUtilities: Type analysis and mapping utilities
-
rh-foundation::loader: Package downloading functionality (module in rh-foundation)PackageLoader: HTTP client for registry interactionLoaderConfig: Configuration for registry access- Tarball download and extraction
- Registry response parsing
-
lib.rs: Public API and error definitions- Re-exports from modules for convenience
- Centralized error types (
CodegenError) - Common result type (
CodegenResult<T>)
Supporting Modules
config.rs: Configuration management and serializationfhir_types.rs: FHIR type definitions and parsingrust_types.rs: Rust type generation and formattingtype_mapper.rs: FHIR to Rust type mapping logicvalue_sets.rs: Value set handling and enum generation
Error Handling
All functions return CodegenResult<T> which is an alias for anyhow::Result<T>:
use ;
Features
Implemented
- Parse FHIR StructureDefinition JSON
- Generate Rust structs with proper field types
- Handle optional fields (min: 0)
- Handle array fields (max: "*" or > 1)
- FHIR primitive type mappings
- Enum generation for required value set bindings
- serde rename for snake_case fields
- Documentation generation with proper Rust doc comment formatting
- FHIR package downloading from npm-style registries
- Automatic extraction and processing of package tarballs
- Authentication support for private registries
- Type caching to avoid duplicate generation
- Modular generator architecture for maintainability
- Compile-time metadata generation for type resolution
- Primitive field extension support
In Progress
- Complex type references and inheritance
- Dynamic ValueSet fetching from FHIR servers
- Extension handling and extension definitions
- Profile validation and constraint checking
Planned
- Custom type generators for dates, URIs, etc.
- Integration with FHIR validation libraries
- Support for FHIR GraphQL schema generation
- Performance optimizations for large packages
Testing
Run the test suite:
The tests cover:
- StructureDefinition parsing
- Rust type generation
- Configuration loading
- Package downloading (with mocked HTTP)
- Enum generation for value sets
- Error handling and edge cases
CLI Tool
This library is used by the rh-cli CLI tool in apps/rh-cli/. See the CLI documentation for command-line usage examples.
Contributing
To contribute to the rh-codegen library:
- Code Style: Follow the project's Rust conventions (see
.github/copilot-instructions.md) - Testing: Add tests for new functionality
- Documentation: Update doc comments and this README
- Error Handling: Use
anyhow::Resultwith proper context - Performance: Consider caching and optimization for large-scale generation
Development Commands
# Run tests
# Check formatting
# Run clippy
# Generate documentation
The generated code is designed to be idiomatic Rust that integrates seamlessly with the serde ecosystem for JSON serialization and deserialization.