@atomic-ehr/fhirpath
Version:
A TypeScript implementation of FHIRPath
80 lines (72 loc) • 2.38 kB
text/typescript
import type { FunctionDefinition, FunctionEvaluator } from '../types';
import { Errors } from '../errors';
import { box, unbox } from '../boxing';
export const evaluate: FunctionEvaluator = async (input, context, args, evaluator) => {
// abs() takes no arguments
if (args.length !== 0) {
throw Errors.wrongArgumentCount('abs', 0, args.length);
}
// If input is empty, return empty
if (input.length === 0) {
return { value: [], context };
}
// If input has multiple items, error
if (input.length > 1) {
throw Errors.singletonRequired('abs', input.length);
}
const boxedValue = input[0];
if (!boxedValue) return { value: [], context };
const value = unbox(boxedValue);
// Handle different types
if (typeof value === 'number') {
const result = Math.abs(value);
const typeInfo = Number.isInteger(result) ?
{ type: 'Integer' as const, singleton: true } :
{ type: 'Decimal' as const, singleton: true };
return { value: [box(result, typeInfo)], context };
}
// Handle Quantity type
if (value && typeof value === 'object' && 'value' in value && 'unit' in value) {
const result = {
value: Math.abs(value.value),
unit: value.unit,
...(value._ucumQuantity && { _ucumQuantity: { ...value._ucumQuantity, value: Math.abs(value._ucumQuantity.value) } })
};
return {
value: [box(result, { type: 'Quantity', singleton: true })],
context
};
}
throw Errors.invalidOperandType('abs', `${typeof value}`);
};
export const absFunction: FunctionDefinition & { evaluate: FunctionEvaluator } = {
name: 'abs',
category: ['math'],
description: 'Returns the absolute value of the input. When taking the absolute value of a quantity, the unit is unchanged.',
examples: [
'(-5).abs()',
'(-5.5).abs()',
"(-5.5 'mg').abs()"
],
signatures: [
{
name: 'abs-integer',
input: { type: 'Integer', singleton: true },
parameters: [],
result: { type: 'Integer', singleton: true }
},
{
name: 'abs-decimal',
input: { type: 'Decimal', singleton: true },
parameters: [],
result: { type: 'Decimal', singleton: true }
},
{
name: 'abs-quantity',
input: { type: 'Quantity', singleton: true },
parameters: [],
result: { type: 'Quantity', singleton: true }
}
],
evaluate
};