use helios_fhirpath_support::EvaluationError;
use helios_fhirpath_support::EvaluationResult;
use std::collections::HashSet;
pub fn subset_of_function(
invocation_base: &EvaluationResult,
other_collection: &EvaluationResult,
) -> Result<EvaluationResult, EvaluationError> {
let self_items = match invocation_base {
EvaluationResult::Collection { items, .. } => items,
EvaluationResult::Empty => return Ok(EvaluationResult::boolean(true)), single => &[single.clone()][..], };
let other_items = match other_collection {
EvaluationResult::Collection { items, .. } => items,
EvaluationResult::Empty => &[][..], single => &[single.clone()][..], };
let other_set: HashSet<_> = other_items.iter().collect();
let is_subset = self_items.iter().all(|item| other_set.contains(item));
Ok(EvaluationResult::boolean(is_subset))
}
pub fn superset_of_function(
invocation_base: &EvaluationResult,
other_collection: &EvaluationResult,
) -> Result<EvaluationResult, EvaluationError> {
let self_items = match invocation_base {
EvaluationResult::Collection { items, .. } => items,
EvaluationResult::Empty => &[][..],
single => &[single.clone()][..],
};
let other_items = match other_collection {
EvaluationResult::Collection { items, .. } => items,
EvaluationResult::Empty => return Ok(EvaluationResult::boolean(true)), single => &[single.clone()][..],
};
let self_set: HashSet<_> = self_items.iter().collect();
let is_superset = other_items.iter().all(|item| self_set.contains(item));
Ok(EvaluationResult::boolean(is_superset))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_subset_of_simple_collections() {
let collection1 = EvaluationResult::Collection {
items: vec![EvaluationResult::integer(1), EvaluationResult::integer(2)],
has_undefined_order: false,
type_info: None,
};
let collection2 = EvaluationResult::Collection {
items: vec![
EvaluationResult::integer(1),
EvaluationResult::integer(2),
EvaluationResult::integer(3),
],
has_undefined_order: false,
type_info: None,
};
let result = subset_of_function(&collection1, &collection2).unwrap();
assert_eq!(result, EvaluationResult::boolean(true));
let result = subset_of_function(&collection2, &collection1).unwrap();
assert_eq!(result, EvaluationResult::boolean(false));
}
#[test]
fn test_subset_of_empty_collections() {
let empty = EvaluationResult::Empty;
let collection = EvaluationResult::Collection {
items: vec![EvaluationResult::integer(1), EvaluationResult::integer(2)],
has_undefined_order: false,
type_info: None,
};
let result = subset_of_function(&empty, &collection).unwrap();
assert_eq!(result, EvaluationResult::boolean(true));
let result = subset_of_function(&collection, &empty).unwrap();
assert_eq!(result, EvaluationResult::boolean(false));
}
#[test]
fn test_subset_of_with_single_items() {
let item1 = EvaluationResult::integer(1);
let collection = EvaluationResult::Collection {
items: vec![EvaluationResult::integer(1), EvaluationResult::integer(2)],
has_undefined_order: false,
type_info: None,
};
let result = subset_of_function(&item1, &collection).unwrap();
assert_eq!(result, EvaluationResult::boolean(true));
let item3 = EvaluationResult::integer(3);
let result = subset_of_function(&item3, &collection).unwrap();
assert_eq!(result, EvaluationResult::boolean(false));
}
#[test]
fn test_superset_of_simple_collections() {
let collection1 = EvaluationResult::Collection {
items: vec![EvaluationResult::integer(1), EvaluationResult::integer(2)],
has_undefined_order: false,
type_info: None,
};
let collection2 = EvaluationResult::Collection {
items: vec![
EvaluationResult::integer(1),
EvaluationResult::integer(2),
EvaluationResult::integer(3),
],
has_undefined_order: false,
type_info: None,
};
let result = superset_of_function(&collection2, &collection1).unwrap();
assert_eq!(result, EvaluationResult::boolean(true));
let result = superset_of_function(&collection1, &collection2).unwrap();
assert_eq!(result, EvaluationResult::boolean(false));
}
#[test]
fn test_superset_of_empty_collections() {
let empty = EvaluationResult::Empty;
let collection = EvaluationResult::Collection {
items: vec![EvaluationResult::integer(1), EvaluationResult::integer(2)],
has_undefined_order: false,
type_info: None,
};
let result = superset_of_function(&collection, &empty).unwrap();
assert_eq!(result, EvaluationResult::boolean(true));
let result = superset_of_function(&empty, &collection).unwrap();
assert_eq!(result, EvaluationResult::boolean(false));
}
#[test]
fn test_superset_of_with_single_items() {
let item1 = EvaluationResult::integer(1);
let collection = EvaluationResult::Collection {
items: vec![EvaluationResult::integer(1), EvaluationResult::integer(2)],
has_undefined_order: false,
type_info: None,
};
let result = superset_of_function(&collection, &item1).unwrap();
assert_eq!(result, EvaluationResult::boolean(true));
let item3 = EvaluationResult::integer(3);
let result = superset_of_function(&collection, &item3).unwrap();
assert_eq!(result, EvaluationResult::boolean(false));
}
#[test]
fn test_equal_collections() {
let collection1 = EvaluationResult::Collection {
items: vec![EvaluationResult::integer(1), EvaluationResult::integer(2)],
has_undefined_order: false,
type_info: None,
};
let collection2 = EvaluationResult::Collection {
items: vec![EvaluationResult::integer(1), EvaluationResult::integer(2)],
has_undefined_order: false,
type_info: None,
};
let result = subset_of_function(&collection1, &collection2).unwrap();
assert_eq!(result, EvaluationResult::boolean(true));
let result = superset_of_function(&collection1, &collection2).unwrap();
assert_eq!(result, EvaluationResult::boolean(true));
}
}