Skip to main content

haste_fhir_converter/
lib.rs

1use liquid_core::Expression;
2use liquid_core::Runtime;
3use liquid_core::{
4    Display_filter, Filter, FilterParameters, FilterReflection, FromFilterParameters, ParseFilter,
5};
6use liquid_core::{Error, Result};
7use liquid_core::{Value, ValueView};
8use tokio::runtime::Handle;
9
10#[derive(Debug, FilterParameters)]
11struct FHIRPathArgs {
12    #[parameter(description = "The FHIRPath expression to evaluate.", arg_type = "str")]
13    fhirpath: Expression,
14}
15
16#[derive(Clone, ParseFilter, FilterReflection)]
17#[filter(
18    name = "fhirpath",
19    description = "Evaluates a FHIRPath expression.",
20    parameters(FHIRPathArgs),
21    parsed(FHIRPathFilter)
22)]
23pub struct FHIRPath;
24
25#[derive(Debug, FromFilterParameters, Display_filter)]
26#[name = "fhirpath"]
27struct FHIRPathFilter {
28    #[parameters]
29    args: FHIRPathArgs,
30}
31
32impl Filter for FHIRPathFilter {
33    fn evaluate(&self, _input: &dyn ValueView, runtime: &dyn Runtime) -> Result<Value> {
34        let args = self.args.evaluate(runtime)?;
35
36        let fhirpath = args.fhirpath;
37
38        // let view_value = input.to_value();
39
40        if !fhirpath.is_empty() {
41            let result = tokio::task::block_in_place(|| {
42                Handle::current().block_on(async {
43                    haste_fhirpath::FPEngine::new()
44                        .evaluate(fhirpath.as_str(), vec![])
45                        .await
46                })
47            })
48            .map_err(|err| Error::with_msg(format!("FHIRPath evaluation error: {}", err)))?;
49
50            let k = result
51                .iter()
52                .map(|v| Value::scalar(format!("{:?}", v)))
53                .collect::<Vec<_>>();
54
55            Ok(k.into())
56        } else {
57            Err(Error::with_msg("FHIRPath expression cannot be empty"))
58        }
59    }
60}
61
62pub fn fhir_converter() {
63    let template = liquid::ParserBuilder::with_stdlib()
64        .filter(FHIRPath)
65        .build()
66        .unwrap()
67        .parse("Liquid! {{num | fhirpath: '5.5 / 2'}}")
68        .unwrap();
69
70    let globals = liquid::object!({
71        "num": 4f64
72    });
73
74    let output = template.render(&globals).unwrap();
75
76    println!("{}", output);
77}