use crate::evaluator::EvaluationContext;
use helios_fhirpath_support::{EvaluationError, EvaluationResult};
use rust_decimal::prelude::ToPrimitive;
pub fn to_long(
input: &EvaluationResult,
_context: &EvaluationContext,
) -> Result<EvaluationResult, EvaluationError> {
match input {
EvaluationResult::Collection { items, .. } => {
if items.len() == 1 {
to_long(&items[0], _context)
} else {
Ok(EvaluationResult::Empty)
}
}
EvaluationResult::Integer(i, _, _) => Ok(EvaluationResult::integer(*i)),
EvaluationResult::Decimal(d, _, _) => match d.to_i64() {
Some(i) => Ok(EvaluationResult::integer(i)),
None => Ok(EvaluationResult::Empty),
},
EvaluationResult::Boolean(b, _, _) => {
if *b {
Ok(EvaluationResult::integer(1))
} else {
Ok(EvaluationResult::integer(0))
}
}
EvaluationResult::String(s, _, _) => match s.parse::<i64>() {
Ok(i) => Ok(EvaluationResult::integer(i)),
Err(_) => Ok(EvaluationResult::Empty),
},
_ => Ok(EvaluationResult::Empty),
}
}
pub fn converts_to_long(
input: &EvaluationResult,
_context: &EvaluationContext,
) -> Result<EvaluationResult, EvaluationError> {
match input {
EvaluationResult::Collection { items, .. } => {
if items.len() == 1 {
converts_to_long(&items[0], _context)
} else {
Ok(EvaluationResult::boolean(false))
}
}
EvaluationResult::Integer(_, _, _) => Ok(EvaluationResult::boolean(true)),
EvaluationResult::Decimal(d, _, _) => Ok(EvaluationResult::boolean(d.to_i64().is_some())),
EvaluationResult::Boolean(_, _, _) => Ok(EvaluationResult::boolean(true)),
EvaluationResult::String(s, _, _) => {
Ok(EvaluationResult::boolean(s.parse::<i64>().is_ok()))
}
_ => Ok(EvaluationResult::boolean(false)),
}
}
#[cfg(test)]
mod tests {
use super::*;
use rust_decimal_macros::dec;
#[test]
fn test_to_long_integer() {
let context = EvaluationContext::new_empty_with_default_version();
let result = to_long(&EvaluationResult::integer(42), &context).unwrap();
assert_eq!(result, EvaluationResult::integer(42));
let result = to_long(&EvaluationResult::integer(-42), &context).unwrap();
assert_eq!(result, EvaluationResult::integer(-42));
let result = to_long(&EvaluationResult::integer(0), &context).unwrap();
assert_eq!(result, EvaluationResult::integer(0));
}
#[test]
fn test_to_long_decimal() {
let context = EvaluationContext::new_empty_with_default_version();
let result = to_long(&EvaluationResult::decimal(dec!(42.75)), &context).unwrap();
assert_eq!(result, EvaluationResult::integer(42));
let result = to_long(&EvaluationResult::decimal(dec!(-42.75)), &context).unwrap();
assert_eq!(result, EvaluationResult::integer(-42));
let result = to_long(&EvaluationResult::decimal(dec!(0.999)), &context).unwrap();
assert_eq!(result, EvaluationResult::integer(0));
}
#[test]
fn test_to_long_boolean() {
let context = EvaluationContext::new_empty_with_default_version();
let result = to_long(&EvaluationResult::boolean(true), &context).unwrap();
assert_eq!(result, EvaluationResult::integer(1));
let result = to_long(&EvaluationResult::boolean(false), &context).unwrap();
assert_eq!(result, EvaluationResult::integer(0));
}
#[test]
fn test_to_long_string() {
let context = EvaluationContext::new_empty_with_default_version();
let result = to_long(&EvaluationResult::string("42".to_string()), &context).unwrap();
assert_eq!(result, EvaluationResult::integer(42));
let result = to_long(&EvaluationResult::string("-42".to_string()), &context).unwrap();
assert_eq!(result, EvaluationResult::integer(-42));
let result = to_long(
&EvaluationResult::string("not a number".to_string()),
&context,
)
.unwrap();
assert_eq!(result, EvaluationResult::Empty);
let result = to_long(&EvaluationResult::string("42.5".to_string()), &context).unwrap();
assert_eq!(result, EvaluationResult::Empty);
}
#[test]
fn test_to_long_collection() {
let context = EvaluationContext::new_empty_with_default_version();
let collection = EvaluationResult::Collection {
items: vec![EvaluationResult::integer(42)],
has_undefined_order: false,
type_info: None,
};
let result = to_long(&collection, &context).unwrap();
assert_eq!(result, EvaluationResult::integer(42));
let collection = EvaluationResult::Collection {
items: vec![EvaluationResult::integer(42), EvaluationResult::integer(43)],
has_undefined_order: false,
type_info: None,
};
let result = to_long(&collection, &context).unwrap();
assert_eq!(result, EvaluationResult::Empty);
let collection = EvaluationResult::Collection {
items: vec![],
has_undefined_order: false,
type_info: None,
};
let result = to_long(&collection, &context).unwrap();
assert_eq!(result, EvaluationResult::Empty);
}
#[test]
fn test_to_long_other_types() {
let context = EvaluationContext::new_empty_with_default_version();
let result = to_long(&EvaluationResult::date("2022-01-01".to_string()), &context).unwrap();
assert_eq!(result, EvaluationResult::Empty);
let result = to_long(
&EvaluationResult::datetime("2022-01-01T12:00:00".to_string()),
&context,
)
.unwrap();
assert_eq!(result, EvaluationResult::Empty);
let result = to_long(&EvaluationResult::time("12:00:00".to_string()), &context).unwrap();
assert_eq!(result, EvaluationResult::Empty);
let result = to_long(&EvaluationResult::Empty, &context).unwrap();
assert_eq!(result, EvaluationResult::Empty);
let map = std::collections::HashMap::new();
let result = to_long(
&EvaluationResult::Object {
map,
type_info: None,
},
&context,
)
.unwrap();
assert_eq!(result, EvaluationResult::Empty);
}
#[test]
fn test_converts_to_long() {
let context = EvaluationContext::new_empty_with_default_version();
assert_eq!(
converts_to_long(&EvaluationResult::integer(42), &context).unwrap(),
EvaluationResult::boolean(true)
);
assert_eq!(
converts_to_long(&EvaluationResult::decimal(dec!(42.75)), &context).unwrap(),
EvaluationResult::boolean(true)
);
assert_eq!(
converts_to_long(&EvaluationResult::boolean(true), &context).unwrap(),
EvaluationResult::boolean(true)
);
assert_eq!(
converts_to_long(&EvaluationResult::string("42".to_string()), &context).unwrap(),
EvaluationResult::boolean(true)
);
assert_eq!(
converts_to_long(
&EvaluationResult::string("not a number".to_string()),
&context
)
.unwrap(),
EvaluationResult::boolean(false)
);
assert_eq!(
converts_to_long(&EvaluationResult::date("2022-01-01".to_string()), &context).unwrap(),
EvaluationResult::boolean(false)
);
assert_eq!(
converts_to_long(&EvaluationResult::Empty, &context).unwrap(),
EvaluationResult::boolean(false)
);
let collection = EvaluationResult::Collection {
items: vec![EvaluationResult::integer(42)],
has_undefined_order: false,
type_info: None,
};
assert_eq!(
converts_to_long(&collection, &context).unwrap(),
EvaluationResult::boolean(true)
);
let collection = EvaluationResult::Collection {
items: vec![EvaluationResult::integer(42), EvaluationResult::integer(43)],
has_undefined_order: false,
type_info: None,
};
assert_eq!(
converts_to_long(&collection, &context).unwrap(),
EvaluationResult::boolean(false)
);
}
}