Coverage for src/lumen/fhirpath/engine/util.py: 89%
66 statements
« prev ^ index » next coverage.py v7.16.0, created at 2026-08-31 18:46 +0000
« prev ^ index » next coverage.py v7.16.0, created at 2026-08-31 18:46 +0000
1from decimal import Decimal
2import json
3from collections import OrderedDict
4from functools import reduce
5from lumen.fhirpath.engine.nodes import ResourceNode, FP_Quantity
8class set_paths:
9 def __init__(self, func, parsedPath, model=None, options=None):
10 self.func = func
11 self.parsedPath = parsedPath
12 self.model = model
13 self.options = options
15 def __call__(self, resource, context=None):
16 return self.func(
17 resource, self.parsedPath, context or {}, self.model, self.options
18 )
21def get_data(value):
22 if isinstance(value, ResourceNode):
23 value = value.data
25 if isinstance(value, float):
26 return Decimal(str(value))
27 return value
30def parse_value(value):
31 def parse_complex_value(v):
32 if isinstance(v, FP_Quantity):
33 return v
34 num_value, unit = v.get("value"), v.get("code")
35 return FP_Quantity(num_value, f"'{unit}'") if num_value and unit else None
37 return (
38 parse_complex_value(value.data)
39 if getattr(value, "get_type_info", lambda: None)()
40 and value.get_type_info().name == "Quantity"
41 else value
42 )
45def is_number(value):
46 return isinstance(value, (int, Decimal, complex)) and not isinstance(value, bool)
49def is_capitalized(x):
50 return isinstance(x, str) and x[0] == x[0].upper()
53def is_empty(x):
54 return isinstance(x, list) and len(x) == 0
57def is_some(x):
58 return x is not None and not is_empty(x)
61def is_nullable(x):
62 return x is None or is_empty(x)
65def is_true(x):
66 return x == True or isinstance(x, list) and len(x) == 1 and x[0] == True
69def arraify(x, instead_none=None):
70 if isinstance(x, list):
71 return x
72 if is_some(x):
73 return [x]
74 return [] if instead_none is None else [instead_none]
77def flatten(x):
78 def func(acc, x):
79 if isinstance(x, list):
80 acc = acc + x
81 else:
82 acc.append(x)
84 return acc
86 return reduce(func, x, [])
89def uniq(arr):
90 # Strong type fast implementation for unique values that preserves ordering
91 ordered_dict = OrderedDict()
92 for x in arr:
93 try:
94 key = json.dumps(x, sort_keys=True)
95 except TypeError:
96 key = str(x)
97 ordered_dict[key] = x
98 return list(ordered_dict.values())
101def val_data_converted(val):
102 if isinstance(val, ResourceNode):
103 val = val.convert_data()
105 return val
108def process_user_invocation_table(table):
109 return {
110 name: {
111 **entity,
112 "fn": lambda ctx, inputs, *args, __fn__=entity["fn"]: __fn__(
113 [get_data(i) for i in inputs], *args
114 ),
115 }
116 for name, entity in table.items()
117 }