haste_fhir_converter/
lib.rs1use 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 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}