fhirpathrs 0.1.1

Fhirpath implementation in Rust
Documentation
use serde_json::{Number, Value};

use crate::{
    error::FhirpathError,
    evaluate::{EvaluateResult, Evaluate, Text},
    parser::expression::PolarityExpression,
};

use super::resource_node::ResourceNode;

impl Evaluate for PolarityExpression {
    fn evaluate<'a, 'b>(&self, input: &'a ResourceNode<'a, 'b>) -> EvaluateResult<ResourceNode<'a, 'b>> {
        let child = self.children.first();

        child
            .ok_or(FhirpathError::EvaluateError {
                msg: "PolarityExpression must have a single child expression".to_string(),
            })
            .and_then(|child_expr| child_expr.evaluate(input))
            .and_then(|result| Ok(result.get_single()?))
            .and_then(|expr_result| match expr_result {
                Value::Number(json_num) => {
                    let mut num: i64 = json_num.as_i64().ok_or(FhirpathError::EvaluateError {
                        msg: "PolarityExpression result was not a number".to_string(),
                    })?;

                    if self.op == "-" {
                        num = -num;
                    }

                    Ok(Value::Number(Number::from(num)))
                }
                _ => Err(FhirpathError::EvaluateError {
                    msg: "PolarityExpression result was not a number".to_string(),
                }),
            })
            .and_then(|result| Ok(ResourceNode::from_node(input, result)))
    }
}

impl Text for PolarityExpression {
    fn text(&self) -> EvaluateResult<String> {
        Ok(format!(
            "{}{}",
            self.op.clone(),
            self.children
                .iter()
                .map(|c| c.text())
                .collect::<EvaluateResult<Vec<String>>>()?
                .join("")
        ))
    }
}