helios-sof 0.1.47

This crate provides a complete implementation of the SQL-on-FHIR specification for Rust, enabling the transformation of FHIR resources into tabular data using declarative ViewDefinitions. It supports all major FHIR versions (R4, R4B, R5, R6) through a version-agnostic abstraction layer.
Documentation
use criterion::{BenchmarkId, Criterion, black_box, criterion_group, criterion_main};
use helios_sof::{ContentType, SofBundle, SofViewDefinition, run_view_definition};

fn create_large_bundle(num_patients: usize) -> String {
    let mut entries = Vec::new();

    for i in 0..num_patients {
        entries.push(format!(
            r#"{{
            "resource": {{
                "resourceType": "Patient",
                "id": "patient-{}",
                "identifier": [{{
                    "system": "http://example.org",
                    "value": "ID-{}"
                }}],
                "name": [{{
                    "given": ["John-{}"],
                    "family": "Doe-{}"
                }}],
                "gender": "{}",
                "birthDate": "1970-01-{:02}"
            }}
        }}"#,
            i,
            i,
            i,
            i,
            if i % 2 == 0 { "male" } else { "female" },
            (i % 28) + 1
        ));
    }

    format!(
        r#"{{
        "resourceType": "Bundle",
        "type": "collection",
        "entry": [{}]
    }}"#,
        entries.join(",")
    )
}

fn create_complex_view_definition() -> &'static str {
    r#"{
        "resourceType": "ViewDefinition",
        "status": "active",
        "resource": "Patient",
        "select": [
            {
                "column": [
                    {"name": "patient_id", "path": "id"},
                    {"name": "identifier_value", "path": "identifier[0].value"},
                    {"name": "first_name", "path": "name[0].given[0]"},
                    {"name": "last_name", "path": "name[0].family"},
                    {"name": "gender", "path": "gender"},
                    {"name": "birth_date", "path": "birthDate"},
                    {"name": "identifier_system", "path": "identifier[0].system"},
                    {"name": "name_use", "path": "name[0].use"},
                    {"name": "has_identifier", "path": "identifier.exists()"},
                    {"name": "name_count", "path": "name.count()"}
                ]
            }
        ]
    }"#
}

fn benchmark_parallel_processing(c: &mut Criterion) {
    let view_definition_json = create_complex_view_definition();
    let view_def_r4: helios_fhir::r4::ViewDefinition =
        serde_json::from_str(view_definition_json).expect("Failed to parse ViewDefinition");
    let view_definition = SofViewDefinition::R4(view_def_r4);

    let mut group = c.benchmark_group("parallel_resource_processing");

    for num_patients in [10, 50, 100, 200, 500].iter() {
        let bundle_json = create_large_bundle(*num_patients);
        let bundle_r4: helios_fhir::r4::Bundle =
            serde_json::from_str(&bundle_json).expect("Failed to parse Bundle");
        let bundle = SofBundle::R4(bundle_r4);

        group.bench_with_input(
            BenchmarkId::from_parameter(num_patients),
            num_patients,
            |b, _| {
                b.iter(|| {
                    let result = run_view_definition(
                        black_box(view_definition.clone()),
                        black_box(bundle.clone()),
                        black_box(ContentType::Csv),
                    );

                    match result {
                        Ok(_) => {}
                        Err(e) => panic!("Error running view definition: {}", e),
                    }
                });
            },
        );
    }

    group.finish();
}

fn benchmark_with_foreach(c: &mut Criterion) {
    let view_definition_with_foreach = r#"{
        "resourceType": "ViewDefinition",
        "status": "active",
        "resource": "Patient",
        "select": [
            {
                "forEach": "identifier",
                "column": [
                    {"name": "patient_id", "path": "%parent.id"},
                    {"name": "identifier_system", "path": "system"},
                    {"name": "identifier_value", "path": "value"}
                ]
            }
        ]
    }"#;

    let view_def_r4: helios_fhir::r4::ViewDefinition =
        serde_json::from_str(view_definition_with_foreach).expect("Failed to parse ViewDefinition");
    let view_definition = SofViewDefinition::R4(view_def_r4);

    let mut group = c.benchmark_group("parallel_foreach_processing");

    for num_patients in [10, 50, 100, 200].iter() {
        let bundle_json = create_large_bundle(*num_patients);
        let bundle_r4: helios_fhir::r4::Bundle =
            serde_json::from_str(&bundle_json).expect("Failed to parse Bundle");
        let bundle = SofBundle::R4(bundle_r4);

        group.bench_with_input(
            BenchmarkId::from_parameter(num_patients),
            num_patients,
            |b, _| {
                b.iter(|| {
                    let result = run_view_definition(
                        black_box(view_definition.clone()),
                        black_box(bundle.clone()),
                        black_box(ContentType::Csv),
                    );

                    match result {
                        Ok(_) => {}
                        Err(e) => panic!("Error running view definition: {}", e),
                    }
                });
            },
        );
    }

    group.finish();
}

criterion_group!(
    benches,
    benchmark_parallel_processing,
    benchmark_with_foreach
);
criterion_main!(benches);