fml-engine 0.2.1

StructureMap engine for the FHIR Mapping Language: run maps over FHIR JSON
Documentation
# fml-engine

A StructureMap engine for the [FHIR Mapping Language](https://build.fhir.org/ig/HL7/mapping-language-ig/):
runs maps over FHIR JSON, the way the HL7 reference engine does.

- **Passes the reference tests.** Every JSON structure-mapping test of the
  [FHIR test cases]https://github.com/FHIR/fhir-test-cases (12 of 12, R4B and R5).
- **Converts FHIR versions.** With the HL7 [cross-version maps]https://github.com/HL7/fhir-cross-version
  and their ConceptMaps, it converts 2,863 of the 2,881 R4 specification examples that have a
  map to R5: R4 `medicationReference` becomes the R5 CodeableReference, Encounter `class` becomes a
  list of CodeableConcepts, and so on. A code a ConceptMap does not know is left out, as the
  reference engine does, and reported in `warnings`.
- **The whole language.** Groups and `extends`, source filters (type, `where`, `check`, `log`,
  list modes, `default`), targets that create or reuse elements (repeating, choice elements written
  as `valueReference`, `share`), dependent groups, default groups chosen by type, imported maps,
  primitives with their `id` and extensions, and rules with several sources.
- **Transforms:** `create`, `copy`, `evaluate`, `truncate`, `cast`, `append`, `translate`,
  `reference`, `pointer`, `uuid`, `cc`, `c`, `id`, `cp`, `qty`, `escape` (html, xml, json), and
  the IG's date and time transforms: `toDateTime`, `toDate`, `toTime` with format patterns
  (`dd/MM/yyyy HH:mm`, `MMMM d, yyyy`, …) and `unixToDateTime`, `unixToDate`, `unixToTime`.
  Not yet: `dateOp`, which the IG lists without defining.
- **Produced resources.** Resources a map creates outside the target (a `create` with no target
  element) come back in `produced`, ready for a Bundle.
- **Follows the IG where it says more than the reference engine.** Named groups and nested rules
  after `then` both run; a source's `min..max` is enforced; `evaluate` with several values makes
  one target per value; a group name in several imported maps is an error; `cast` takes `FHIR.`
  and `System.` types and checks the value.
- **Debug trace.** `with_trace(true)` records the trace of the IG's debug page for
  `$transform?debug=true`: `enter` / `step` / `exit` events with their depth, the position in the
  StructureMap (`StructureMap.group[0].rule[2]`) and the variables in scope. `debug_parameters`
  writes the `Parameters` response with `traceStatus` (`complete`, `truncated`, `stopped`), the
  text range of each event (rows and UTF-16 columns, from `fml_model::Locations`), and an
  `outcome` with the failure and where it happened, why events were left out, and values left out
  of the result.
- **Safe to run on maps you did not write.** `Limits` bound the group depth, the rules run, the
  values created and the size of the trace; a flag cancels a run. Failures say what kind they are
  (`ErrorKind`) and where (`position`).
- **Pluggable.** Structure definitions come from [fml-check]https://crates.io/crates/fml-check's
  `Definitions`, FHIRPath from an `Expressions` implementation (the `fhirpath` feature uses
  [octofhir-fhirpath]https://crates.io/crates/octofhir-fhirpath), imported maps from a
  `MapResolver`, ConceptMaps from a `ConceptMapResolver`, and any other ConceptMap through a
  `TranslateService` (`$translate` on a terminology server). ConceptMaps are found by URL and by
  the canonical URLs they replace. `uuid()` and new ids come from an `IdGenerator`
  (`SequentialIds` makes runs repeatable).

```rust
use fml_check::{CoreDefinitions, Release};
use fml_engine::{ConceptMapSet, Engine, FhirPathExpressions, Limits, MapSet};

let definitions = CoreDefinitions::new(Release::R5);
let expressions = FhirPathExpressions::new(Release::R5).await?;
let output = Engine::new(&definitions, expressions)
    .with_maps(&maps)                 // MapSet: StructureMaps for `imports`
    .with_concept_maps(&concept_maps) // ConceptMapSet: for translate()
    .with_limits(Limits::default())   // depth, rules, values, trace size
    .transform(&map, &input)
    .await?;
println!("{}", output.target);        // also: output.produced, output.warnings
```

Part of [fml-rs](https://github.com/octofhir/fml-rs). Licensed under MIT or Apache-2.0.