pysof 0.1.32__tar.gz → 0.1.42__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pysof-0.1.42/Cargo.toml +40 -0
- {pysof-0.1.32 → pysof-0.1.42}/PKG-INFO +6 -4
- {pysof-0.1.32/crates/pysof → pysof-0.1.42}/README.md +3 -3
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhir/Cargo.toml +5 -4
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhir/build.rs +81 -16
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhir/src/lib.rs +180 -14
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhir/src/parameters.rs +2 -13
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhir/src/r4.rs +1097 -199
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhir/src/r4b.rs +1072 -195
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhir/src/r5.rs +1214 -236
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhir/src/r6.rs +1446 -1951
- pysof-0.1.42/crates/fhir/tests/test_contained_stack.rs +113 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhir-macro/Cargo.toml +2 -1
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhir-macro/src/lib.rs +586 -245
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/Cargo.toml +3 -2
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/README.md +68 -6
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/benches/server_benches.rs +0 -2
- pysof-0.1.42/crates/fhirpath/src/debug_trace.rs +175 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/evaluator.rs +194 -14
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/handlers.rs +167 -35
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/lib.rs +5 -5
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/models.rs +120 -7
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/parse_debug.rs +257 -1
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/parser.rs +1036 -34
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/context_trace_test.rs +4 -2
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r5/tests-fhir-r5.xml +13 -5
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/debug_datetime_boundary.rs +2 -2
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/debug_string_boundary_tests.rs +3 -1
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/evaluator_tests.rs +269 -10
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/fhir_boundary_tests.rs +7 -5
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/join_function_test.rs +15 -5
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/r4_tests.rs +3 -2
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/r5_tests.rs +12 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/reference_key_debug.rs +1 -1
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath-support/Cargo.toml +1 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath-support/src/lib.rs +20 -2
- pysof-0.1.42/crates/pysof/Cargo.toml +41 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/PYPI_CHECKLIST.md +4 -4
- {pysof-0.1.32 → pysof-0.1.42/crates/pysof}/README.md +3 -3
- {pysof-0.1.32 → pysof-0.1.42/crates/pysof}/src/lib.rs +9 -9
- pysof-0.1.42/crates/serde-support/Cargo.toml +17 -0
- pysof-0.1.42/crates/serde-support/src/lib.rs +684 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/Cargo.toml +4 -3
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/README.md +51 -1
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/src/cli.rs +4 -3
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/src/data_source.rs +15 -10
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/src/server.rs +4 -3
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/debug_boolean_test.rs +3 -1
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/debug_datetime_instant_constants.rs +3 -1
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/debug_extension_function.rs +1 -1
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/debug_extension_macro_fix.rs +1 -1
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/debug_fhir_resource_structure.rs +2 -2
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/debug_inequality.rs +1 -1
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/debug_instant_constant.rs +3 -1
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/extension_debug_test.rs +1 -1
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_boolean_constant_debug2.rs +1 -1
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_boolean_constant_debug3.rs +1 -1
- {pysof-0.1.32 → pysof-0.1.42}/pyproject.toml +1 -0
- {pysof-0.1.32/crates/pysof → pysof-0.1.42}/src/lib.rs +9 -9
- pysof-0.1.32/Cargo.toml +0 -34
- pysof-0.1.32/crates/fhir/tests/test_examples.rs +0 -420
- pysof-0.1.32/crates/fhir/tests/test_serde.rs +0 -1922
- pysof-0.1.32/crates/pysof/Cargo.toml +0 -35
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhir/README.md +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhir/src/r6.rs.template +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhir/tests/integer_string_integration.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhir/tests/simple_null_test.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhir-macro/README.md +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/PRECISION_LIMITATION.md +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/benches/cli_benches.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/benches/evaluator_benches.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/benches/parser_benches.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/examples/test_ucum.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/grammar/fhirpath.g4 +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/server-api.md +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/aggregate_function.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/bin/fhirpath-cli.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/bin/fhirpath-server.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/boolean_functions.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/boundary_functions.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/cli.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/collection_functions.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/collection_navigation.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/contains_function.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/conversion_functions.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/date_operation.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/datetime_impl.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/distinct_functions.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/error.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/extension_function.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/fhir_type_hierarchy.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/json_utils.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/long_conversion.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/not_function.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/polymorphic_access.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/reference_key_functions.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/repeat_function.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/resource_type.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/server.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/set_operations.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/subset_functions.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/terminology_client.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/terminology_functions.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/trace_function.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/type_function.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/type_inference.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/src/ucum.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/all_function_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/boundary_debug_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/boundary_function_integration_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/comment_test.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/common/context.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/common/mod.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/common/parser.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/common/runner.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r4/input/observation-example.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r4/input/observation-example.xml +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r4/input/patient-example.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r4/input/patient-example.xml +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r4/input/questionnaire-example.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r4/input/questionnaire-example.xml +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r4/input/valueset-example-expansion.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r4/input/valueset-example-expansion.xml +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r4/tests-fhir-r4.xml +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r5/input/appointment-examplereq.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r5/input/ccda.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r5/input/codesystem-example.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r5/input/conceptmap-example.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r5/input/explanationofbenefit-example.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r5/input/observation-example.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r5/input/observation-example.xml +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r5/input/parameters-example-types.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r5/input/patient-container-example.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r5/input/patient-example-name.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r5/input/patient-example-period.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r5/input/patient-example.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r5/input/patient-name-extensions.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r5/input/questionnaire-example.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r5/input/valueset-example-expansion.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/r5/known-test-failures.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/data/testSchema.xsd +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/date_operation_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/datetime_boundary_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/define_variable_test.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/enhanced_variable_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/extension_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/is_as_method_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/oftype_datetime_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/parse_debug_test.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/parser_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/polymorphic_r4_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/polymorphic_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/precision_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/test_boundary_zero.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/trace_api_test.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/trace_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/tree_navigation_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/truncate_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/type_operation_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/type_preservation_integration_test.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/type_reflection_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/uri_type_test.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath/tests/uuid_type_preservation_test.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath-support/README.md +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/fhirpath-support/src/type_info.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/.gitignore +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/Cargo.lock +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/Makefile +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/WHEEL_BUILDING.md +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/multithreading_example.py +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/python-tests/__init__.py +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/python-tests/test_content_types.py +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/python-tests/test_core_functions.py +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/python-tests/test_error_handling.py +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/python-tests/test_fhir_versions.py +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/python-tests/test_import.py +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/python-tests/test_package_metadata.py +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/python-tests/test_source_errors.py +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/scripts/build-wheels.py +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/src/pysof/__init__.py +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/src/pysof/_pysof.pyi +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/src/pysof/py.typed +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/test_multithreading.py +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/tests/integration/content_types.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/tests/integration/error_handling.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/tests/integration/fhir_versions.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/tests/integration/mod.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/tests/integration.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/tests/lib_coverage_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/tests/lib_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/tests/multithreading_integration.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/tests/threading_test.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/pysof/uv.lock +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/benches/parallel_processing_bench.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/src/error.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/src/handlers.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/src/lib.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/src/mod.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/src/models.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/src/parquet_schema.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/src/streaming.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/src/traits.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/common/mod.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/debug_column_ordering.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/debug_datetime_type_info.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/debug_enum_conversion.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/debug_evaluation_result_conversion.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/debug_extension_simple.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/debug_foreach_combinations.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/debug_instant_type_info.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/debug_raw_resource.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/debug_reference_key_types.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/foreach_test.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/multiselect_test.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/run_foreach_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/server_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql-on-fhir-v2/tests/basic.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql-on-fhir-v2/tests/collection.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql-on-fhir-v2/tests/combinations.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql-on-fhir-v2/tests/constant.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql-on-fhir-v2/tests/constant_types.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql-on-fhir-v2/tests/fhirpath.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql-on-fhir-v2/tests/fhirpath_numbers.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql-on-fhir-v2/tests/fn_boundary.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql-on-fhir-v2/tests/fn_empty.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql-on-fhir-v2/tests/fn_extension.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql-on-fhir-v2/tests/fn_first.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql-on-fhir-v2/tests/fn_join.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql-on-fhir-v2/tests/fn_oftype.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql-on-fhir-v2/tests/fn_reference_keys.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql-on-fhir-v2/tests/foreach.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql-on-fhir-v2/tests/logic.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql-on-fhir-v2/tests/repeat.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql-on-fhir-v2/tests/union.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql-on-fhir-v2/tests/validate.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql-on-fhir-v2/tests/view_resource.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql-on-fhir-v2/tests/where.json +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/sql_on_fhir_tests.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_base64_binary_constant.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_boolean_constant_debug.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_boolean_validation.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_chunked_processing.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_cli_file_source.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_csv_quote_handling.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_extension_fix_verification.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_extension_value_access.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_format_parameter_body.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_header_parameter_body.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_limit_parameter_body.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_ndjson_input.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_parallel_working.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_parameter_validation.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_parquet_export.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_parquet_large_dataset.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_parquet_server_options.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_patient_reference_formats.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_query_parameter_combinations.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_run_operation_parameters.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_runner_integration.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_shortened_format_names.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_where_clause_validation.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/crates/sof/tests/test_x_ndjson_support.rs +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/src/pysof/__init__.py +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/src/pysof/_pysof.cpython-311-darwin.so +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/src/pysof/_pysof.pyi +0 -0
- {pysof-0.1.32 → pysof-0.1.42}/src/pysof/py.typed +0 -0
pysof-0.1.42/Cargo.toml
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "pysof"
|
|
3
|
+
version.workspace = true
|
|
4
|
+
edition = "2024"
|
|
5
|
+
description = "Python bindings for helios-sof using PyO3"
|
|
6
|
+
license.workspace = true
|
|
7
|
+
authors.workspace = true
|
|
8
|
+
repository.workspace = true
|
|
9
|
+
homepage = "https://github.com/HeliosSoftware/hfs/tree/main/crates/pysof"
|
|
10
|
+
rust-version.workspace = true
|
|
11
|
+
keywords = ["helios-software", "hl7", "fhir", "helios-fhir-server", "sql-on-fhir"]
|
|
12
|
+
|
|
13
|
+
# PyO3 extension metadata
|
|
14
|
+
[lib]
|
|
15
|
+
name = "pysof"
|
|
16
|
+
crate-type = ["cdylib"]
|
|
17
|
+
|
|
18
|
+
[dependencies]
|
|
19
|
+
pyo3 = { version = ">=0.27", features = ["extension-module", "generate-import-lib"] }
|
|
20
|
+
helios-sof = { path = "../sof", version = "0.1.42" }
|
|
21
|
+
helios-fhir = { path = "../fhir", version = "0.1.42" }
|
|
22
|
+
serde = { workspace = true }
|
|
23
|
+
serde_json = { workspace = true }
|
|
24
|
+
chrono = { version = "0.4", features = ["serde"] }
|
|
25
|
+
pythonize = "0.27"
|
|
26
|
+
csv = "1.3"
|
|
27
|
+
|
|
28
|
+
[features]
|
|
29
|
+
default = ["R4"]
|
|
30
|
+
R4 = ["helios-sof/R4", "helios-fhir/R4"]
|
|
31
|
+
R4B = ["helios-sof/R4B", "helios-fhir/R4B"]
|
|
32
|
+
R5 = ["helios-sof/R5", "helios-fhir/R5"]
|
|
33
|
+
R6 = ["helios-sof/R6", "helios-fhir/R6"]
|
|
34
|
+
|
|
35
|
+
# Vendor OpenSSL when cross-compiling for Linux ARM64
|
|
36
|
+
[target.'cfg(all(target_arch = "aarch64", target_os = "linux"))'.dependencies]
|
|
37
|
+
openssl = { version = "0.10", features = ["vendored"] }
|
|
38
|
+
|
|
39
|
+
[build-dependencies]
|
|
40
|
+
pyo3-build-config = "0.27"
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pysof
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.42
|
|
4
4
|
Classifier: Programming Language :: Python :: 3
|
|
5
5
|
Classifier: Programming Language :: Python :: 3.10
|
|
6
6
|
Classifier: Programming Language :: Python :: 3.11
|
|
7
7
|
Classifier: Programming Language :: Python :: 3.12
|
|
8
8
|
Classifier: Programming Language :: Python :: 3.13
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
9
10
|
Classifier: License :: OSI Approved :: MIT License
|
|
10
11
|
Classifier: Operating System :: OS Independent
|
|
11
12
|
Classifier: Development Status :: 4 - Beta
|
|
@@ -15,6 +16,7 @@ Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
|
|
|
15
16
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
17
|
Summary: Python wrapper for the Helios Software SOF (SQL on FHIR) toolkit.
|
|
17
18
|
Keywords: SQL on FHIR,FHIR,healthcare,sof,Helios Software
|
|
19
|
+
Home-Page: https://github.com/HeliosSoftware/hfs/tree/main/crates/pysof
|
|
18
20
|
Author-email: Helios Software <team@heliossoftware.com>
|
|
19
21
|
License: MIT
|
|
20
22
|
Requires-Python: >=3.10
|
|
@@ -77,7 +79,7 @@ pip install pysof
|
|
|
77
79
|
- **Linux**: x86_64 (glibc and musl)
|
|
78
80
|
- **Windows**: x86_64 (MSVC)
|
|
79
81
|
- **macOS**: AArch64 (Apple Silicon)
|
|
80
|
-
- **Python**: 3.10, 3.11, 3.12, 3.13
|
|
82
|
+
- **Python**: 3.10, 3.11, 3.12, 3.13, 3.14
|
|
81
83
|
|
|
82
84
|
### From GitHub Releases
|
|
83
85
|
|
|
@@ -346,7 +348,7 @@ Use `pysof.get_supported_fhir_versions()` to check available versions in your bu
|
|
|
346
348
|
|
|
347
349
|
### Requirements
|
|
348
350
|
|
|
349
|
-
- Python 3.10 or later (3.10, 3.11, 3.12, 3.13 supported)
|
|
351
|
+
- Python 3.10 or later (3.10, 3.11, 3.12, 3.13, 3.14 supported)
|
|
350
352
|
- uv (package and environment manager)
|
|
351
353
|
- Rust toolchain (for building from source)
|
|
352
354
|
|
|
@@ -378,7 +380,7 @@ For Python development, it's recommended to use `maturin` via `uv`:
|
|
|
378
380
|
cd crates/pysof
|
|
379
381
|
|
|
380
382
|
# Create a venv with your preferred Python version (3.10+)
|
|
381
|
-
uv venv --python 3.11 # or 3.10, 3.12, 3.13
|
|
383
|
+
uv venv --python 3.11 # or 3.10, 3.12, 3.13, 3.14
|
|
382
384
|
|
|
383
385
|
# Install the project dev dependencies
|
|
384
386
|
uv sync --group dev
|
|
@@ -50,7 +50,7 @@ pip install pysof
|
|
|
50
50
|
- **Linux**: x86_64 (glibc and musl)
|
|
51
51
|
- **Windows**: x86_64 (MSVC)
|
|
52
52
|
- **macOS**: AArch64 (Apple Silicon)
|
|
53
|
-
- **Python**: 3.10, 3.11, 3.12, 3.13
|
|
53
|
+
- **Python**: 3.10, 3.11, 3.12, 3.13, 3.14
|
|
54
54
|
|
|
55
55
|
### From GitHub Releases
|
|
56
56
|
|
|
@@ -319,7 +319,7 @@ Use `pysof.get_supported_fhir_versions()` to check available versions in your bu
|
|
|
319
319
|
|
|
320
320
|
### Requirements
|
|
321
321
|
|
|
322
|
-
- Python 3.10 or later (3.10, 3.11, 3.12, 3.13 supported)
|
|
322
|
+
- Python 3.10 or later (3.10, 3.11, 3.12, 3.13, 3.14 supported)
|
|
323
323
|
- uv (package and environment manager)
|
|
324
324
|
- Rust toolchain (for building from source)
|
|
325
325
|
|
|
@@ -351,7 +351,7 @@ For Python development, it's recommended to use `maturin` via `uv`:
|
|
|
351
351
|
cd crates/pysof
|
|
352
352
|
|
|
353
353
|
# Create a venv with your preferred Python version (3.10+)
|
|
354
|
-
uv venv --python 3.11 # or 3.10, 3.12, 3.13
|
|
354
|
+
uv venv --python 3.11 # or 3.10, 3.12, 3.13, 3.14
|
|
355
355
|
|
|
356
356
|
# Install the project dev dependencies
|
|
357
357
|
uv sync --group dev
|
|
@@ -8,6 +8,7 @@ authors.workspace = true
|
|
|
8
8
|
repository.workspace = true
|
|
9
9
|
homepage = "https://github.com/HeliosSoftware/hfs/tree/main/crates/fhir"
|
|
10
10
|
readme = "README.md"
|
|
11
|
+
keywords = ["helios-software", "hl7", "fhir", "helios-fhir-server", "healthcare"]
|
|
11
12
|
exclude = ["tests/data/**"]
|
|
12
13
|
|
|
13
14
|
[features]
|
|
@@ -17,13 +18,15 @@ R4B = []
|
|
|
17
18
|
R5 = []
|
|
18
19
|
R6 = []
|
|
19
20
|
skip-r6-download = []
|
|
21
|
+
xml = ["helios-serde-support/xml"]
|
|
20
22
|
|
|
21
23
|
[dependencies]
|
|
22
24
|
serde = { workspace = true }
|
|
23
25
|
serde_json = { workspace = true, features = ["raw_value"] }
|
|
24
26
|
clap = { version = "4.0", features = ["derive"] }
|
|
25
|
-
helios-fhir-macro = { path = "../fhir-macro", version = "0.1.
|
|
26
|
-
helios-
|
|
27
|
+
helios-fhir-macro = { path = "../fhir-macro", version = "0.1.42" }
|
|
28
|
+
helios-serde-support = { path = "../serde-support", version = "0.1.42" }
|
|
29
|
+
helios-fhirpath-support = { path = "../fhirpath-support", version = "0.1.42" }
|
|
27
30
|
time = "0.3"
|
|
28
31
|
chrono = { workspace = true }
|
|
29
32
|
# Re-add serde-with-arbitrary-precision, keep macros
|
|
@@ -39,5 +42,3 @@ zip = "0.6"
|
|
|
39
42
|
[package.metadata.docs.rs]
|
|
40
43
|
all-features = true
|
|
41
44
|
rustdoc-args = ["--cfg", "docsrs"]
|
|
42
|
-
|
|
43
|
-
|
|
@@ -18,16 +18,34 @@ fn main() {
|
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
let json_resources_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/data/json/R6");
|
|
22
|
+
let xml_resources_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/data/xml/R6");
|
|
23
|
+
|
|
24
|
+
// Create the resources directories if they don't exist
|
|
25
|
+
fs::create_dir_all(&json_resources_dir).expect("Failed to create JSON resources directory");
|
|
26
|
+
fs::create_dir_all(&xml_resources_dir).expect("Failed to create XML resources directory");
|
|
27
|
+
|
|
28
|
+
// Check if test data is recent (skip download if less than 24 hours old)
|
|
29
|
+
// Use a marker file to track when we last downloaded
|
|
30
|
+
let marker_path = json_resources_dir.join(".download_marker");
|
|
31
|
+
if let Ok(metadata) = fs::metadata(&marker_path) {
|
|
32
|
+
if let Ok(modified) = metadata.modified() {
|
|
33
|
+
if let Ok(duration) = modified.elapsed() {
|
|
34
|
+
if duration.as_secs() < 86400 {
|
|
35
|
+
println!("cargo:warning=R6 test data is recent, skipping download");
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
24
41
|
|
|
25
|
-
|
|
26
|
-
fs::create_dir_all(&resources_dir).expect("Failed to create resources directory");
|
|
42
|
+
println!("cargo:warning=Downloading R6 test data from HL7 build server");
|
|
27
43
|
|
|
28
|
-
let
|
|
44
|
+
let json_url = "https://build.fhir.org/examples-json.zip";
|
|
45
|
+
let xml_url = "https://build.fhir.org/examples.zip";
|
|
29
46
|
|
|
30
|
-
let
|
|
47
|
+
let json_output_path = json_resources_dir.join("examples.json.zip");
|
|
48
|
+
let xml_output_path = xml_resources_dir.join("examples.xml.zip");
|
|
31
49
|
|
|
32
50
|
println!("Downloading test data ...");
|
|
33
51
|
|
|
@@ -40,12 +58,15 @@ fn main() {
|
|
|
40
58
|
|
|
41
59
|
// Try downloading with retries
|
|
42
60
|
const MAX_RETRIES: u32 = 3;
|
|
61
|
+
|
|
62
|
+
// Download JSON examples
|
|
63
|
+
println!("Downloading JSON examples...");
|
|
43
64
|
let mut last_error = None;
|
|
44
65
|
|
|
45
66
|
for attempt in 1..=MAX_RETRIES {
|
|
46
|
-
println!("
|
|
67
|
+
println!("JSON download attempt {} of {}", attempt, MAX_RETRIES);
|
|
47
68
|
|
|
48
|
-
match download_with_retry(&client,
|
|
69
|
+
match download_with_retry(&client, json_url, &json_output_path) {
|
|
49
70
|
Ok(bytes) => {
|
|
50
71
|
println!("Downloaded {} bytes", bytes);
|
|
51
72
|
last_error = None;
|
|
@@ -66,13 +87,59 @@ fn main() {
|
|
|
66
87
|
|
|
67
88
|
if let Some(error) = last_error {
|
|
68
89
|
panic!(
|
|
69
|
-
"Failed to download file after {} attempts: {}",
|
|
90
|
+
"Failed to download JSON file after {} attempts: {}",
|
|
70
91
|
MAX_RETRIES, error
|
|
71
92
|
);
|
|
72
93
|
}
|
|
73
94
|
|
|
95
|
+
// Extract JSON examples
|
|
96
|
+
extract_and_clean(&json_output_path, &json_resources_dir, "examples.json.zip");
|
|
97
|
+
|
|
98
|
+
// Download XML examples
|
|
99
|
+
println!("Downloading XML examples...");
|
|
100
|
+
last_error = None;
|
|
101
|
+
|
|
102
|
+
for attempt in 1..=MAX_RETRIES {
|
|
103
|
+
println!("XML download attempt {} of {}", attempt, MAX_RETRIES);
|
|
104
|
+
|
|
105
|
+
match download_with_retry(&client, xml_url, &xml_output_path) {
|
|
106
|
+
Ok(bytes) => {
|
|
107
|
+
println!("Downloaded {} bytes", bytes);
|
|
108
|
+
last_error = None;
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
Err(e) => {
|
|
112
|
+
println!("Attempt {} failed: {}", attempt, e);
|
|
113
|
+
last_error = Some(e);
|
|
114
|
+
|
|
115
|
+
if attempt < MAX_RETRIES {
|
|
116
|
+
let wait_time = Duration::from_secs(5 * attempt as u64);
|
|
117
|
+
println!("Waiting {:?} before retry...", wait_time);
|
|
118
|
+
thread::sleep(wait_time);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if let Some(error) = last_error {
|
|
125
|
+
panic!(
|
|
126
|
+
"Failed to download XML file after {} attempts: {}",
|
|
127
|
+
MAX_RETRIES, error
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Extract XML examples
|
|
132
|
+
extract_and_clean(&xml_output_path, &xml_resources_dir, "examples.xml.zip");
|
|
133
|
+
|
|
134
|
+
// Write marker file to track download time
|
|
135
|
+
fs::write(&marker_path, "").expect("Failed to write download marker");
|
|
136
|
+
|
|
137
|
+
println!("FHIR test data downloaded successfully");
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
fn extract_and_clean(zip_path: &PathBuf, resources_dir: &PathBuf, zip_filename: &str) {
|
|
74
141
|
// Verify and extract the downloaded file
|
|
75
|
-
let file = fs::File::open(
|
|
142
|
+
let file = fs::File::open(zip_path).expect("Failed to open downloaded file");
|
|
76
143
|
let metadata = file.metadata().expect("Failed to get file metadata");
|
|
77
144
|
println!("File size on disk: {} bytes", metadata.len());
|
|
78
145
|
|
|
@@ -84,12 +151,12 @@ fn main() {
|
|
|
84
151
|
|
|
85
152
|
// Clean out the resources directory before extracting (removes old files that may no longer exist in the zip)
|
|
86
153
|
println!("cargo:warning=Cleaning resources directory before extraction...");
|
|
87
|
-
for entry in fs::read_dir(
|
|
154
|
+
for entry in fs::read_dir(resources_dir).unwrap() {
|
|
88
155
|
let entry = entry.unwrap();
|
|
89
156
|
let path = entry.path();
|
|
90
157
|
|
|
91
158
|
// Skip the zip file itself
|
|
92
|
-
if path.file_name() == Some(std::ffi::OsStr::new(
|
|
159
|
+
if path.file_name() == Some(std::ffi::OsStr::new(zip_filename)) {
|
|
93
160
|
continue;
|
|
94
161
|
}
|
|
95
162
|
|
|
@@ -122,9 +189,7 @@ fn main() {
|
|
|
122
189
|
}
|
|
123
190
|
|
|
124
191
|
// Delete the zip file after extraction
|
|
125
|
-
fs::remove_file(
|
|
126
|
-
|
|
127
|
-
println!("FHIR test data downloaded successfully");
|
|
192
|
+
fs::remove_file(zip_path).expect("Failed to delete zip file");
|
|
128
193
|
}
|
|
129
194
|
|
|
130
195
|
fn download_with_retry(
|
|
@@ -43,6 +43,9 @@
|
|
|
43
43
|
|
|
44
44
|
use chrono::{DateTime as ChronoDateTime, NaiveDate, NaiveTime, Utc};
|
|
45
45
|
use helios_fhirpath_support::{EvaluationResult, IntoEvaluationResult, TypeInfoResult};
|
|
46
|
+
#[cfg(feature = "xml")]
|
|
47
|
+
use helios_serde_support::SingleOrVec;
|
|
48
|
+
|
|
46
49
|
use rust_decimal::Decimal;
|
|
47
50
|
use serde::{
|
|
48
51
|
Deserialize, Serialize,
|
|
@@ -1432,6 +1435,8 @@ pub mod parameters;
|
|
|
1432
1435
|
// Re-export commonly used types from parameters module
|
|
1433
1436
|
pub use parameters::{ParameterValueAccessor, VersionIndependentParameters};
|
|
1434
1437
|
|
|
1438
|
+
// Internal helpers used by the derive macro; not part of the public API
|
|
1439
|
+
#[doc(hidden)]
|
|
1435
1440
|
/// Multi-version FHIR resource container supporting version-agnostic operations.
|
|
1436
1441
|
///
|
|
1437
1442
|
/// This enum provides a unified interface for working with FHIR resources across
|
|
@@ -1471,7 +1476,7 @@ pub use parameters::{ParameterValueAccessor, VersionIndependentParameters};
|
|
|
1471
1476
|
/// };
|
|
1472
1477
|
///
|
|
1473
1478
|
/// // Wrap in version-agnostic container
|
|
1474
|
-
/// let resource = FhirResource::R4(Box::new(helios_fhir::r4::Resource::Patient(patient)));
|
|
1479
|
+
/// let resource = FhirResource::R4(Box::new(helios_fhir::r4::Resource::Patient(Box::new(patient))));
|
|
1475
1480
|
/// assert_eq!(resource.version(), FhirVersion::R4);
|
|
1476
1481
|
/// }
|
|
1477
1482
|
/// ```
|
|
@@ -1618,7 +1623,7 @@ impl FhirResource {
|
|
|
1618
1623
|
/// version: FhirVersion,
|
|
1619
1624
|
/// }
|
|
1620
1625
|
/// ```
|
|
1621
|
-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
1626
|
+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
1622
1627
|
pub enum FhirVersion {
|
|
1623
1628
|
/// FHIR 4.0.1 (normative) - The current normative version
|
|
1624
1629
|
#[cfg(feature = "R4")]
|
|
@@ -1674,6 +1679,155 @@ impl FhirVersion {
|
|
|
1674
1679
|
FhirVersion::R6 => "R6",
|
|
1675
1680
|
}
|
|
1676
1681
|
}
|
|
1682
|
+
|
|
1683
|
+
/// Parse from MIME-type parameter value (e.g., "4.0", "5.0").
|
|
1684
|
+
///
|
|
1685
|
+
/// Per FHIR spec: <https://hl7.org/fhir/http.html#version-parameter>
|
|
1686
|
+
///
|
|
1687
|
+
/// # Arguments
|
|
1688
|
+
///
|
|
1689
|
+
/// * `value` - The MIME-type parameter value (e.g., "4.0", "4.3", "5.0", "6.0")
|
|
1690
|
+
///
|
|
1691
|
+
/// # Returns
|
|
1692
|
+
///
|
|
1693
|
+
/// The corresponding `FhirVersion` if the value matches an enabled version,
|
|
1694
|
+
/// or `None` if not recognized or the version feature is not enabled.
|
|
1695
|
+
///
|
|
1696
|
+
/// # Examples
|
|
1697
|
+
///
|
|
1698
|
+
/// ```rust
|
|
1699
|
+
/// use helios_fhir::FhirVersion;
|
|
1700
|
+
///
|
|
1701
|
+
/// # #[cfg(feature = "R4")]
|
|
1702
|
+
/// assert_eq!(FhirVersion::from_mime_param("4.0"), Some(FhirVersion::R4));
|
|
1703
|
+
/// # #[cfg(feature = "R5")]
|
|
1704
|
+
/// assert_eq!(FhirVersion::from_mime_param("5.0"), Some(FhirVersion::R5));
|
|
1705
|
+
/// assert_eq!(FhirVersion::from_mime_param("invalid"), None);
|
|
1706
|
+
/// ```
|
|
1707
|
+
pub fn from_mime_param(value: &str) -> Option<Self> {
|
|
1708
|
+
match value.trim() {
|
|
1709
|
+
#[cfg(feature = "R4")]
|
|
1710
|
+
"4.0" => Some(FhirVersion::R4),
|
|
1711
|
+
#[cfg(feature = "R4B")]
|
|
1712
|
+
"4.3" => Some(FhirVersion::R4B),
|
|
1713
|
+
#[cfg(feature = "R5")]
|
|
1714
|
+
"5.0" => Some(FhirVersion::R5),
|
|
1715
|
+
#[cfg(feature = "R6")]
|
|
1716
|
+
"6.0" => Some(FhirVersion::R6),
|
|
1717
|
+
_ => None,
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1721
|
+
/// Returns the MIME-type parameter value for this version.
|
|
1722
|
+
///
|
|
1723
|
+
/// This value is used in Content-Type and Accept headers per FHIR spec.
|
|
1724
|
+
/// Example: `application/fhir+json; fhirVersion=4.0`
|
|
1725
|
+
///
|
|
1726
|
+
/// # Examples
|
|
1727
|
+
///
|
|
1728
|
+
/// ```rust
|
|
1729
|
+
/// use helios_fhir::FhirVersion;
|
|
1730
|
+
///
|
|
1731
|
+
/// # #[cfg(feature = "R4")]
|
|
1732
|
+
/// assert_eq!(FhirVersion::R4.as_mime_param(), "4.0");
|
|
1733
|
+
/// # #[cfg(feature = "R5")]
|
|
1734
|
+
/// assert_eq!(FhirVersion::R5.as_mime_param(), "5.0");
|
|
1735
|
+
/// ```
|
|
1736
|
+
pub fn as_mime_param(&self) -> &'static str {
|
|
1737
|
+
match self {
|
|
1738
|
+
#[cfg(feature = "R4")]
|
|
1739
|
+
FhirVersion::R4 => "4.0",
|
|
1740
|
+
#[cfg(feature = "R4B")]
|
|
1741
|
+
FhirVersion::R4B => "4.3",
|
|
1742
|
+
#[cfg(feature = "R5")]
|
|
1743
|
+
FhirVersion::R5 => "5.0",
|
|
1744
|
+
#[cfg(feature = "R6")]
|
|
1745
|
+
FhirVersion::R6 => "6.0",
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
/// Returns the full version string (e.g., "4.0.1", "5.0.0").
|
|
1750
|
+
///
|
|
1751
|
+
/// This is the complete version identifier used in CapabilityStatement.fhirVersion.
|
|
1752
|
+
///
|
|
1753
|
+
/// # Examples
|
|
1754
|
+
///
|
|
1755
|
+
/// ```rust
|
|
1756
|
+
/// use helios_fhir::FhirVersion;
|
|
1757
|
+
///
|
|
1758
|
+
/// # #[cfg(feature = "R4")]
|
|
1759
|
+
/// assert_eq!(FhirVersion::R4.full_version(), "4.0.1");
|
|
1760
|
+
/// # #[cfg(feature = "R5")]
|
|
1761
|
+
/// assert_eq!(FhirVersion::R5.full_version(), "5.0.0");
|
|
1762
|
+
/// ```
|
|
1763
|
+
pub fn full_version(&self) -> &'static str {
|
|
1764
|
+
match self {
|
|
1765
|
+
#[cfg(feature = "R4")]
|
|
1766
|
+
FhirVersion::R4 => "4.0.1",
|
|
1767
|
+
#[cfg(feature = "R4B")]
|
|
1768
|
+
FhirVersion::R4B => "4.3.0",
|
|
1769
|
+
#[cfg(feature = "R5")]
|
|
1770
|
+
FhirVersion::R5 => "5.0.0",
|
|
1771
|
+
#[cfg(feature = "R6")]
|
|
1772
|
+
FhirVersion::R6 => "6.0.0",
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
/// Parse from database storage string.
|
|
1777
|
+
///
|
|
1778
|
+
/// Accepts both MIME format ("4.0") and short format ("R4") for flexibility.
|
|
1779
|
+
/// This is useful when loading version information from the database.
|
|
1780
|
+
///
|
|
1781
|
+
/// # Arguments
|
|
1782
|
+
///
|
|
1783
|
+
/// * `value` - The storage value (e.g., "4.0", "R4", "r4")
|
|
1784
|
+
///
|
|
1785
|
+
/// # Returns
|
|
1786
|
+
///
|
|
1787
|
+
/// The corresponding `FhirVersion` if recognized, or `None` otherwise.
|
|
1788
|
+
///
|
|
1789
|
+
/// # Examples
|
|
1790
|
+
///
|
|
1791
|
+
/// ```rust
|
|
1792
|
+
/// use helios_fhir::FhirVersion;
|
|
1793
|
+
///
|
|
1794
|
+
/// # #[cfg(feature = "R4")]
|
|
1795
|
+
/// {
|
|
1796
|
+
/// assert_eq!(FhirVersion::from_storage("4.0"), Some(FhirVersion::R4));
|
|
1797
|
+
/// assert_eq!(FhirVersion::from_storage("R4"), Some(FhirVersion::R4));
|
|
1798
|
+
/// assert_eq!(FhirVersion::from_storage("r4"), Some(FhirVersion::R4));
|
|
1799
|
+
/// }
|
|
1800
|
+
/// ```
|
|
1801
|
+
pub fn from_storage(value: &str) -> Option<Self> {
|
|
1802
|
+
// Try MIME format first
|
|
1803
|
+
Self::from_mime_param(value).or_else(|| match value.to_uppercase().as_str() {
|
|
1804
|
+
#[cfg(feature = "R4")]
|
|
1805
|
+
"R4" => Some(FhirVersion::R4),
|
|
1806
|
+
#[cfg(feature = "R4B")]
|
|
1807
|
+
"R4B" => Some(FhirVersion::R4B),
|
|
1808
|
+
#[cfg(feature = "R5")]
|
|
1809
|
+
"R5" => Some(FhirVersion::R5),
|
|
1810
|
+
#[cfg(feature = "R6")]
|
|
1811
|
+
"R6" => Some(FhirVersion::R6),
|
|
1812
|
+
_ => None,
|
|
1813
|
+
})
|
|
1814
|
+
}
|
|
1815
|
+
|
|
1816
|
+
/// Returns all enabled FHIR versions.
|
|
1817
|
+
///
|
|
1818
|
+
/// This is useful for listing supported versions (e.g., in `$versions` operation).
|
|
1819
|
+
pub fn enabled_versions() -> &'static [FhirVersion] {
|
|
1820
|
+
&[
|
|
1821
|
+
#[cfg(feature = "R4")]
|
|
1822
|
+
FhirVersion::R4,
|
|
1823
|
+
#[cfg(feature = "R4B")]
|
|
1824
|
+
FhirVersion::R4B,
|
|
1825
|
+
#[cfg(feature = "R5")]
|
|
1826
|
+
FhirVersion::R5,
|
|
1827
|
+
#[cfg(feature = "R6")]
|
|
1828
|
+
FhirVersion::R6,
|
|
1829
|
+
]
|
|
1830
|
+
}
|
|
1677
1831
|
}
|
|
1678
1832
|
|
|
1679
1833
|
/// Implements `Display` trait for user-friendly output formatting.
|
|
@@ -1843,7 +1997,15 @@ where
|
|
|
1843
1997
|
if extension.is_some() {
|
|
1844
1998
|
return Err(de::Error::duplicate_field("extension"));
|
|
1845
1999
|
}
|
|
1846
|
-
|
|
2000
|
+
#[cfg(feature = "xml")]
|
|
2001
|
+
{
|
|
2002
|
+
let single_or_vec: SingleOrVec<E> = map.next_value()?;
|
|
2003
|
+
extension = Some(single_or_vec.into());
|
|
2004
|
+
}
|
|
2005
|
+
#[cfg(not(feature = "xml"))]
|
|
2006
|
+
{
|
|
2007
|
+
extension = Some(map.next_value()?);
|
|
2008
|
+
}
|
|
1847
2009
|
}
|
|
1848
2010
|
"value" => {
|
|
1849
2011
|
if value.is_some() {
|
|
@@ -1928,10 +2090,11 @@ pub struct Element<V, E> {
|
|
|
1928
2090
|
}
|
|
1929
2091
|
|
|
1930
2092
|
impl<V, E> Element<V, E> {
|
|
1931
|
-
/// Returns
|
|
1932
|
-
#[inline]
|
|
2093
|
+
/// Returns true when no value, id, or extensions are present.
|
|
1933
2094
|
pub fn is_empty(&self) -> bool {
|
|
1934
|
-
self.value.is_none()
|
|
2095
|
+
self.value.is_none()
|
|
2096
|
+
&& self.id.is_none()
|
|
2097
|
+
&& self.extension.as_ref().is_none_or(|ext| ext.is_empty())
|
|
1935
2098
|
}
|
|
1936
2099
|
}
|
|
1937
2100
|
|
|
@@ -2422,12 +2585,6 @@ impl<E> DecimalElement<E> {
|
|
|
2422
2585
|
value: Some(precise_value),
|
|
2423
2586
|
}
|
|
2424
2587
|
}
|
|
2425
|
-
|
|
2426
|
-
/// Returns `true` if the element has no value, id, or extensions.
|
|
2427
|
-
#[inline]
|
|
2428
|
-
pub fn is_empty(&self) -> bool {
|
|
2429
|
-
self.value.is_none() && self.id.is_none() && self.extension.is_none()
|
|
2430
|
-
}
|
|
2431
2588
|
}
|
|
2432
2589
|
|
|
2433
2590
|
// Custom Deserialize for DecimalElement<E> using intermediate Value
|
|
@@ -2501,8 +2658,17 @@ where
|
|
|
2501
2658
|
if extension.is_some() {
|
|
2502
2659
|
return Err(de::Error::duplicate_field("extension"));
|
|
2503
2660
|
}
|
|
2504
|
-
|
|
2505
|
-
|
|
2661
|
+
#[cfg(feature = "xml")]
|
|
2662
|
+
{
|
|
2663
|
+
let single_or_vec: SingleOrVec<E> =
|
|
2664
|
+
Deserialize::deserialize(v).map_err(de::Error::custom)?;
|
|
2665
|
+
extension = Some(single_or_vec.into());
|
|
2666
|
+
}
|
|
2667
|
+
#[cfg(not(feature = "xml"))]
|
|
2668
|
+
{
|
|
2669
|
+
extension =
|
|
2670
|
+
Deserialize::deserialize(v).map_err(de::Error::custom)?;
|
|
2671
|
+
}
|
|
2506
2672
|
}
|
|
2507
2673
|
"value" => {
|
|
2508
2674
|
if value.is_some() {
|
|
@@ -25,27 +25,16 @@ use serde::{Deserialize, Serialize};
|
|
|
25
25
|
///
|
|
26
26
|
/// ```rust
|
|
27
27
|
/// use helios_fhir::VersionIndependentParameters;
|
|
28
|
-
/// # #[cfg(feature = "R4")]
|
|
29
|
-
/// use helios_fhir::r4::Parameters;
|
|
30
28
|
///
|
|
31
29
|
/// # #[cfg(feature = "R4")]
|
|
32
30
|
/// # {
|
|
33
|
-
/// //
|
|
34
|
-
/// let
|
|
35
|
-
/// "resourceType": "Parameters",
|
|
36
|
-
/// "parameter": [{
|
|
37
|
-
/// "name": "expression",
|
|
38
|
-
/// "valueString": "Patient.name"
|
|
39
|
-
/// }]
|
|
40
|
-
/// }"#;
|
|
41
|
-
///
|
|
42
|
-
/// let params: Parameters = serde_json::from_str(json)?;
|
|
31
|
+
/// // Create Parameters directly (avoids stack overflow on Windows from deep serde recursion)
|
|
32
|
+
/// let params = helios_fhir::r4::Parameters::default();
|
|
43
33
|
/// let version_independent = VersionIndependentParameters::R4(params);
|
|
44
34
|
///
|
|
45
35
|
/// // Check version
|
|
46
36
|
/// assert_eq!(version_independent.version(), helios_fhir::FhirVersion::R4);
|
|
47
37
|
/// # }
|
|
48
|
-
/// # Ok::<(), Box<dyn std::error::Error>>(())
|
|
49
38
|
/// ```
|
|
50
39
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
51
40
|
#[serde(untagged)]
|