use super::{
operation::{
AttributesTreeOperation, MultipleAttributesWithIndexOperation,
SingleAttributeWithIndexOperation,
},
BinaryArithmeticKind, MultipleComparisonKind, MultipleKind, SingleComparisonKind,
SingleKindWithIndex, UnaryArithmeticKind,
};
use crate::{
errors::MedRecordResult,
medrecord::{
querying::{
attributes::{
operation::{
MultipleAttributesWithoutIndexOperation, SingleAttributeWithoutIndexOperation,
},
AttributesTreeContext, MultipleAttributesWithIndexContext,
MultipleAttributesWithoutIndexContext, SingleAttributeWithoutIndexContext,
SingleKindWithoutIndex,
},
operand_traits::{
Abs, Add, Contains, Count, EitherOr, EndsWith, EqualTo, Exclude, GreaterThan,
GreaterThanOrEqualTo, IsIn, IsInt, IsMax, IsMin, IsNotIn, IsString, LessThan,
LessThanOrEqualTo, Lowercase, Max, Min, Mod, Mul, NotEqualTo, Pow, Random, Slice,
StartsWith, Sub, Sum, ToValues, Trim, TrimEnd, TrimStart, Uppercase,
},
values::{MultipleValuesWithIndexContext, MultipleValuesWithIndexOperand},
BoxedIterator, DeepClone, EvaluateBackward, EvaluateForward, EvaluateForwardGrouped,
GroupedIterator, ReduceInput, RootOperand,
},
EdgeOperand, MedRecordAttribute, NodeOperand, Wrapper,
},
MedRecord,
};
use medmodels_utils::{aliases::MrHashSet, traits::ReadWriteOrPanic};
use std::collections::HashSet;
#[derive(Debug, Clone)]
pub enum SingleAttributeComparisonOperand {
NodeSingleAttributeWithIndexOperand(NodeSingleAttributeWithIndexOperand),
NodeSingleAttributeWithoutIndexOperand(NodeSingleAttributeWithoutIndexOperand),
EdgeSingleAttributeWithIndexOperand(EdgeSingleAttributeWithIndexOperand),
EdgeSingleAttributeWithoutIndexOperand(EdgeSingleAttributeWithoutIndexOperand),
Attribute(MedRecordAttribute),
}
impl DeepClone for SingleAttributeComparisonOperand {
fn deep_clone(&self) -> Self {
match self {
Self::NodeSingleAttributeWithIndexOperand(operand) => {
Self::NodeSingleAttributeWithIndexOperand(operand.deep_clone())
}
Self::NodeSingleAttributeWithoutIndexOperand(operand) => {
Self::NodeSingleAttributeWithoutIndexOperand(operand.deep_clone())
}
Self::EdgeSingleAttributeWithIndexOperand(operand) => {
Self::EdgeSingleAttributeWithIndexOperand(operand.deep_clone())
}
Self::EdgeSingleAttributeWithoutIndexOperand(operand) => {
Self::EdgeSingleAttributeWithoutIndexOperand(operand.deep_clone())
}
Self::Attribute(attribute) => Self::Attribute(attribute.clone()),
}
}
}
impl From<Wrapper<NodeSingleAttributeWithIndexOperand>> for SingleAttributeComparisonOperand {
fn from(value: Wrapper<NodeSingleAttributeWithIndexOperand>) -> Self {
Self::NodeSingleAttributeWithIndexOperand(value.0.read_or_panic().deep_clone())
}
}
impl From<&Wrapper<NodeSingleAttributeWithIndexOperand>> for SingleAttributeComparisonOperand {
fn from(value: &Wrapper<NodeSingleAttributeWithIndexOperand>) -> Self {
Self::NodeSingleAttributeWithIndexOperand(value.0.read_or_panic().deep_clone())
}
}
impl From<Wrapper<NodeSingleAttributeWithoutIndexOperand>> for SingleAttributeComparisonOperand {
fn from(value: Wrapper<NodeSingleAttributeWithoutIndexOperand>) -> Self {
Self::NodeSingleAttributeWithoutIndexOperand(value.0.read_or_panic().deep_clone())
}
}
impl From<&Wrapper<NodeSingleAttributeWithoutIndexOperand>> for SingleAttributeComparisonOperand {
fn from(value: &Wrapper<NodeSingleAttributeWithoutIndexOperand>) -> Self {
Self::NodeSingleAttributeWithoutIndexOperand(value.0.read_or_panic().deep_clone())
}
}
impl From<Wrapper<EdgeSingleAttributeWithIndexOperand>> for SingleAttributeComparisonOperand {
fn from(value: Wrapper<EdgeSingleAttributeWithIndexOperand>) -> Self {
Self::EdgeSingleAttributeWithIndexOperand(value.0.read_or_panic().deep_clone())
}
}
impl From<&Wrapper<EdgeSingleAttributeWithIndexOperand>> for SingleAttributeComparisonOperand {
fn from(value: &Wrapper<EdgeSingleAttributeWithIndexOperand>) -> Self {
Self::EdgeSingleAttributeWithIndexOperand(value.0.read_or_panic().deep_clone())
}
}
impl From<Wrapper<EdgeSingleAttributeWithoutIndexOperand>> for SingleAttributeComparisonOperand {
fn from(value: Wrapper<EdgeSingleAttributeWithoutIndexOperand>) -> Self {
Self::EdgeSingleAttributeWithoutIndexOperand(value.0.read_or_panic().deep_clone())
}
}
impl From<&Wrapper<EdgeSingleAttributeWithoutIndexOperand>> for SingleAttributeComparisonOperand {
fn from(value: &Wrapper<EdgeSingleAttributeWithoutIndexOperand>) -> Self {
Self::EdgeSingleAttributeWithoutIndexOperand(value.0.read_or_panic().deep_clone())
}
}
impl<V: Into<MedRecordAttribute>> From<V> for SingleAttributeComparisonOperand {
fn from(value: V) -> Self {
Self::Attribute(value.into())
}
}
impl SingleAttributeComparisonOperand {
pub(crate) fn evaluate_backward(
&self,
medrecord: &MedRecord,
) -> MedRecordResult<Option<MedRecordAttribute>> {
Ok(match self {
Self::NodeSingleAttributeWithIndexOperand(operand) => operand
.evaluate_backward(medrecord)?
.map(|attribute| attribute.1),
Self::NodeSingleAttributeWithoutIndexOperand(operand) => {
operand.evaluate_backward(medrecord)?
}
Self::EdgeSingleAttributeWithIndexOperand(operand) => operand
.evaluate_backward(medrecord)?
.map(|attribute| attribute.1),
Self::EdgeSingleAttributeWithoutIndexOperand(operand) => {
operand.evaluate_backward(medrecord)?
}
Self::Attribute(attribute) => Some(attribute.clone()),
})
}
}
#[derive(Debug, Clone)]
pub enum MultipleAttributesComparisonOperand {
NodeMultipleAttributesWithIndexOperand(NodeMultipleAttributesWithIndexOperand),
NodeMultipleAttributesWithoutIndexOperand(NodeMultipleAttributesWithoutIndexOperand),
EdgeMultipleAttributesWithIndexOperand(EdgeMultipleAttributesWithIndexOperand),
EdgeMultipleAttributesWithoutIndexOperand(EdgeMultipleAttributesWithoutIndexOperand),
Attributes(MrHashSet<MedRecordAttribute>),
}
impl DeepClone for MultipleAttributesComparisonOperand {
fn deep_clone(&self) -> Self {
match self {
Self::NodeMultipleAttributesWithIndexOperand(operand) => {
Self::NodeMultipleAttributesWithIndexOperand(operand.deep_clone())
}
Self::NodeMultipleAttributesWithoutIndexOperand(operand) => {
Self::NodeMultipleAttributesWithoutIndexOperand(operand.deep_clone())
}
Self::EdgeMultipleAttributesWithIndexOperand(operand) => {
Self::EdgeMultipleAttributesWithIndexOperand(operand.deep_clone())
}
Self::EdgeMultipleAttributesWithoutIndexOperand(operand) => {
Self::EdgeMultipleAttributesWithoutIndexOperand(operand.deep_clone())
}
Self::Attributes(attribute) => Self::Attributes(attribute.clone()),
}
}
}
impl From<Wrapper<NodeMultipleAttributesWithIndexOperand>> for MultipleAttributesComparisonOperand {
fn from(value: Wrapper<NodeMultipleAttributesWithIndexOperand>) -> Self {
Self::NodeMultipleAttributesWithIndexOperand(value.0.read_or_panic().deep_clone())
}
}
impl From<&Wrapper<NodeMultipleAttributesWithIndexOperand>>
for MultipleAttributesComparisonOperand
{
fn from(value: &Wrapper<NodeMultipleAttributesWithIndexOperand>) -> Self {
Self::NodeMultipleAttributesWithIndexOperand(value.0.read_or_panic().deep_clone())
}
}
impl From<Wrapper<NodeMultipleAttributesWithoutIndexOperand>>
for MultipleAttributesComparisonOperand
{
fn from(value: Wrapper<NodeMultipleAttributesWithoutIndexOperand>) -> Self {
Self::NodeMultipleAttributesWithoutIndexOperand(value.0.read_or_panic().deep_clone())
}
}
impl From<&Wrapper<NodeMultipleAttributesWithoutIndexOperand>>
for MultipleAttributesComparisonOperand
{
fn from(value: &Wrapper<NodeMultipleAttributesWithoutIndexOperand>) -> Self {
Self::NodeMultipleAttributesWithoutIndexOperand(value.0.read_or_panic().deep_clone())
}
}
impl From<Wrapper<EdgeMultipleAttributesWithIndexOperand>> for MultipleAttributesComparisonOperand {
fn from(value: Wrapper<EdgeMultipleAttributesWithIndexOperand>) -> Self {
Self::EdgeMultipleAttributesWithIndexOperand(value.0.read_or_panic().deep_clone())
}
}
impl From<&Wrapper<EdgeMultipleAttributesWithIndexOperand>>
for MultipleAttributesComparisonOperand
{
fn from(value: &Wrapper<EdgeMultipleAttributesWithIndexOperand>) -> Self {
Self::EdgeMultipleAttributesWithIndexOperand(value.0.read_or_panic().deep_clone())
}
}
impl From<Wrapper<EdgeMultipleAttributesWithoutIndexOperand>>
for MultipleAttributesComparisonOperand
{
fn from(value: Wrapper<EdgeMultipleAttributesWithoutIndexOperand>) -> Self {
Self::EdgeMultipleAttributesWithoutIndexOperand(value.0.read_or_panic().deep_clone())
}
}
impl From<&Wrapper<EdgeMultipleAttributesWithoutIndexOperand>>
for MultipleAttributesComparisonOperand
{
fn from(value: &Wrapper<EdgeMultipleAttributesWithoutIndexOperand>) -> Self {
Self::EdgeMultipleAttributesWithoutIndexOperand(value.0.read_or_panic().deep_clone())
}
}
impl<V: Into<MedRecordAttribute>> From<Vec<V>> for MultipleAttributesComparisonOperand {
fn from(value: Vec<V>) -> Self {
Self::Attributes(value.into_iter().map(Into::into).collect())
}
}
impl<V: Into<MedRecordAttribute>> From<HashSet<V>> for MultipleAttributesComparisonOperand {
fn from(value: HashSet<V>) -> Self {
Self::Attributes(value.into_iter().map(Into::into).collect())
}
}
impl<V: Into<MedRecordAttribute>> From<MrHashSet<V>> for MultipleAttributesComparisonOperand {
fn from(value: MrHashSet<V>) -> Self {
Self::Attributes(value.into_iter().map(Into::into).collect())
}
}
impl<V: Into<MedRecordAttribute> + Clone, const N: usize> From<[V; N]>
for MultipleAttributesComparisonOperand
{
fn from(value: [V; N]) -> Self {
value.to_vec().into()
}
}
impl MultipleAttributesComparisonOperand {
pub(crate) fn evaluate_backward(
&self,
medrecord: &MedRecord,
) -> MedRecordResult<MrHashSet<MedRecordAttribute>> {
Ok(match self {
Self::NodeMultipleAttributesWithIndexOperand(operand) => operand
.evaluate_backward(medrecord)?
.map(|(_, attribute)| attribute)
.collect(),
Self::NodeMultipleAttributesWithoutIndexOperand(operand) => {
operand.evaluate_backward(medrecord)?.collect()
}
Self::EdgeMultipleAttributesWithIndexOperand(operand) => operand
.evaluate_backward(medrecord)?
.map(|(_, attribute)| attribute)
.collect(),
Self::EdgeMultipleAttributesWithoutIndexOperand(operand) => {
operand.evaluate_backward(medrecord)?.collect()
}
Self::Attributes(attributes) => attributes.clone(),
})
}
}
pub type NodeAttributesTreeOperand = AttributesTreeOperand<NodeOperand>;
pub type EdgeAttributesTreeOperand = AttributesTreeOperand<EdgeOperand>;
#[derive(Debug, Clone)]
pub struct AttributesTreeOperand<O: RootOperand> {
context: AttributesTreeContext<O>,
operations: Vec<AttributesTreeOperation<O>>,
}
impl<O: RootOperand> DeepClone for AttributesTreeOperand<O> {
fn deep_clone(&self) -> Self {
Self {
context: self.context.clone(),
operations: self.operations.iter().map(DeepClone::deep_clone).collect(),
}
}
}
impl<'a, O: 'a + RootOperand> EvaluateForward<'a> for AttributesTreeOperand<O> {
type InputValue = BoxedIterator<'a, (&'a O::Index, Vec<MedRecordAttribute>)>;
type ReturnValue = BoxedIterator<'a, (&'a O::Index, Vec<MedRecordAttribute>)>;
fn evaluate_forward(
&self,
medrecord: &'a MedRecord,
attributes: Self::InputValue,
) -> MedRecordResult<Self::ReturnValue> {
let attributes: BoxedIterator<_> = Box::new(attributes);
self.operations
.iter()
.try_fold(attributes, |attribute_tuples, operation| {
operation.evaluate(medrecord, attribute_tuples)
})
}
}
impl<'a, O: 'a + RootOperand> EvaluateForwardGrouped<'a> for AttributesTreeOperand<O> {
fn evaluate_forward_grouped(
&self,
medrecord: &'a MedRecord,
attributes: GroupedIterator<'a, Self::InputValue>,
) -> MedRecordResult<GroupedIterator<'a, Self::ReturnValue>> {
self.operations
.iter()
.try_fold(attributes, |attribute_tuples, operation| {
operation.evaluate_grouped(medrecord, attribute_tuples)
})
}
}
impl<'a, O: 'a + RootOperand> EvaluateBackward<'a> for AttributesTreeOperand<O> {
type ReturnValue = BoxedIterator<'a, (&'a O::Index, Vec<MedRecordAttribute>)>;
fn evaluate_backward(&self, medrecord: &'a MedRecord) -> MedRecordResult<Self::ReturnValue> {
let attributes: BoxedIterator<_> = Box::new(self.context.get_attributes(medrecord)?);
self.evaluate_forward(medrecord, attributes)
}
}
impl<O: RootOperand> Max for AttributesTreeOperand<O> {
type ReturnOperand = MultipleAttributesWithIndexOperand<O>;
fn max(&mut self) -> Wrapper<Self::ReturnOperand> {
let operand = Wrapper::<Self::ReturnOperand>::new(
MultipleAttributesWithIndexContext::AttributesTree {
operand: self.deep_clone(),
kind: MultipleKind::Max,
},
);
self.operations
.push(AttributesTreeOperation::AttributesOperation {
operand: operand.clone(),
});
operand
}
}
impl<O: RootOperand> Min for AttributesTreeOperand<O> {
type ReturnOperand = MultipleAttributesWithIndexOperand<O>;
fn min(&mut self) -> Wrapper<Self::ReturnOperand> {
let operand = Wrapper::<Self::ReturnOperand>::new(
MultipleAttributesWithIndexContext::AttributesTree {
operand: self.deep_clone(),
kind: MultipleKind::Min,
},
);
self.operations
.push(AttributesTreeOperation::AttributesOperation {
operand: operand.clone(),
});
operand
}
}
impl<O: RootOperand> Count for AttributesTreeOperand<O> {
type ReturnOperand = MultipleAttributesWithIndexOperand<O>;
fn count(&mut self) -> Wrapper<Self::ReturnOperand> {
let operand = Wrapper::<Self::ReturnOperand>::new(
MultipleAttributesWithIndexContext::AttributesTree {
operand: self.deep_clone(),
kind: MultipleKind::Count,
},
);
self.operations
.push(AttributesTreeOperation::AttributesOperation {
operand: operand.clone(),
});
operand
}
}
impl<O: RootOperand> Sum for AttributesTreeOperand<O> {
type ReturnOperand = MultipleAttributesWithIndexOperand<O>;
fn sum(&mut self) -> Wrapper<Self::ReturnOperand> {
let operand = Wrapper::<Self::ReturnOperand>::new(
MultipleAttributesWithIndexContext::AttributesTree {
operand: self.deep_clone(),
kind: MultipleKind::Sum,
},
);
self.operations
.push(AttributesTreeOperation::AttributesOperation {
operand: operand.clone(),
});
operand
}
}
impl<O: RootOperand> Random for AttributesTreeOperand<O> {
type ReturnOperand = MultipleAttributesWithIndexOperand<O>;
fn random(&mut self) -> Wrapper<Self::ReturnOperand> {
let operand = Wrapper::<Self::ReturnOperand>::new(
MultipleAttributesWithIndexContext::AttributesTree {
operand: self.deep_clone(),
kind: MultipleKind::Random,
},
);
self.operations
.push(AttributesTreeOperation::AttributesOperation {
operand: operand.clone(),
});
operand
}
}
impl<O: RootOperand> GreaterThan for AttributesTreeOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn greater_than<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
AttributesTreeOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::GreaterThan,
},
);
}
}
impl<O: RootOperand> GreaterThanOrEqualTo for AttributesTreeOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn greater_than_or_equal_to<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
AttributesTreeOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::GreaterThanOrEqualTo,
},
);
}
}
impl<O: RootOperand> LessThan for AttributesTreeOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn less_than<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
AttributesTreeOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::LessThan,
},
);
}
}
impl<O: RootOperand> LessThanOrEqualTo for AttributesTreeOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn less_than_or_equal_to<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
AttributesTreeOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::LessThanOrEqualTo,
},
);
}
}
impl<O: RootOperand> EqualTo for AttributesTreeOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn equal_to<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
AttributesTreeOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::EqualTo,
},
);
}
}
impl<O: RootOperand> NotEqualTo for AttributesTreeOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn not_equal_to<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
AttributesTreeOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::NotEqualTo,
},
);
}
}
impl<O: RootOperand> StartsWith for AttributesTreeOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn starts_with<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
AttributesTreeOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::StartsWith,
},
);
}
}
impl<O: RootOperand> EndsWith for AttributesTreeOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn ends_with<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
AttributesTreeOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::EndsWith,
},
);
}
}
impl<O: RootOperand> Contains for AttributesTreeOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn contains<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
AttributesTreeOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::Contains,
},
);
}
}
impl<O: RootOperand> IsIn for AttributesTreeOperand<O> {
type ComparisonOperand = MultipleAttributesComparisonOperand;
fn is_in<V: Into<Self::ComparisonOperand>>(&mut self, attributes: V) {
self.operations.push(
AttributesTreeOperation::MultipleAttributesComparisonOperation {
operand: attributes.into(),
kind: MultipleComparisonKind::IsIn,
},
);
}
}
impl<O: RootOperand> IsNotIn for AttributesTreeOperand<O> {
type ComparisonOperand = MultipleAttributesComparisonOperand;
fn is_not_in<V: Into<Self::ComparisonOperand>>(&mut self, attributes: V) {
self.operations.push(
AttributesTreeOperation::MultipleAttributesComparisonOperation {
operand: attributes.into(),
kind: MultipleComparisonKind::IsNotIn,
},
);
}
}
impl<O: RootOperand> Add for AttributesTreeOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn add<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations
.push(AttributesTreeOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Add,
});
}
}
impl<O: RootOperand> Sub for AttributesTreeOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn sub<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations
.push(AttributesTreeOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Sub,
});
}
}
impl<O: RootOperand> Mul for AttributesTreeOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn mul<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations
.push(AttributesTreeOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Mul,
});
}
}
impl<O: RootOperand> Pow for AttributesTreeOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn pow<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations
.push(AttributesTreeOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Pow,
});
}
}
impl<O: RootOperand> Mod for AttributesTreeOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn r#mod<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations
.push(AttributesTreeOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Mod,
});
}
}
impl<O: RootOperand> Abs for AttributesTreeOperand<O> {
fn abs(&mut self) {
self.operations
.push(AttributesTreeOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::Abs,
});
}
}
impl<O: RootOperand> Trim for AttributesTreeOperand<O> {
fn trim(&mut self) {
self.operations
.push(AttributesTreeOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::Trim,
});
}
}
impl<O: RootOperand> TrimStart for AttributesTreeOperand<O> {
fn trim_start(&mut self) {
self.operations
.push(AttributesTreeOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::TrimStart,
});
}
}
impl<O: RootOperand> TrimEnd for AttributesTreeOperand<O> {
fn trim_end(&mut self) {
self.operations
.push(AttributesTreeOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::TrimEnd,
});
}
}
impl<O: RootOperand> Lowercase for AttributesTreeOperand<O> {
fn lowercase(&mut self) {
self.operations
.push(AttributesTreeOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::Lowercase,
});
}
}
impl<O: RootOperand> Uppercase for AttributesTreeOperand<O> {
fn uppercase(&mut self) {
self.operations
.push(AttributesTreeOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::Uppercase,
});
}
}
impl<O: RootOperand> Slice for AttributesTreeOperand<O> {
fn slice(&mut self, start: usize, end: usize) {
self.operations
.push(AttributesTreeOperation::Slice(start..end));
}
}
impl<O: RootOperand> IsString for AttributesTreeOperand<O> {
fn is_string(&mut self) {
self.operations.push(AttributesTreeOperation::IsString);
}
}
impl<O: RootOperand> IsInt for AttributesTreeOperand<O> {
fn is_int(&mut self) {
self.operations.push(AttributesTreeOperation::IsInt);
}
}
impl<O: RootOperand> IsMax for AttributesTreeOperand<O> {
fn is_max(&mut self) {
self.operations.push(AttributesTreeOperation::IsMax);
}
}
impl<O: RootOperand> IsMin for AttributesTreeOperand<O> {
fn is_min(&mut self) {
self.operations.push(AttributesTreeOperation::IsMin);
}
}
impl<O: RootOperand> EitherOr for AttributesTreeOperand<O> {
type QueryOperand = Self;
fn either_or<EQ, OQ>(&mut self, either_query: EQ, or_query: OQ)
where
EQ: FnOnce(&mut Wrapper<Self::QueryOperand>),
OQ: FnOnce(&mut Wrapper<Self::QueryOperand>),
{
let mut either_operand = Wrapper::<Self::QueryOperand>::new(self.context.clone());
let mut or_operand = Wrapper::<Self::QueryOperand>::new(self.context.clone());
either_query(&mut either_operand);
or_query(&mut or_operand);
self.operations.push(AttributesTreeOperation::EitherOr {
either: either_operand,
or: or_operand,
});
}
}
impl<O: RootOperand> Exclude for AttributesTreeOperand<O> {
type QueryOperand = Self;
fn exclude<Q>(&mut self, query: Q)
where
Q: FnOnce(&mut Wrapper<Self::QueryOperand>),
{
let mut operand = Wrapper::<Self::QueryOperand>::new(self.context.clone());
query(&mut operand);
self.operations
.push(AttributesTreeOperation::Exclude { operand });
}
}
impl<O: RootOperand> AttributesTreeOperand<O> {
pub(crate) fn new(context: AttributesTreeContext<O>) -> Self {
Self {
context,
operations: Vec::new(),
}
}
pub(crate) fn push_merge_operation(&mut self, operand: Wrapper<AttributesTreeOperand<O>>) {
self.operations
.push(AttributesTreeOperation::Merge { operand });
}
}
impl<O: RootOperand> Wrapper<AttributesTreeOperand<O>> {
pub(crate) fn new(context: AttributesTreeContext<O>) -> Self {
AttributesTreeOperand::new(context).into()
}
pub(crate) fn push_merge_operation(&self, operand: Wrapper<AttributesTreeOperand<O>>) {
self.0.write_or_panic().push_merge_operation(operand);
}
}
pub type NodeMultipleAttributesWithIndexOperand = MultipleAttributesWithIndexOperand<NodeOperand>;
pub type EdgeMultipleAttributesWithIndexOperand = MultipleAttributesWithIndexOperand<EdgeOperand>;
#[derive(Debug, Clone)]
pub struct MultipleAttributesWithIndexOperand<O: RootOperand> {
pub(crate) context: MultipleAttributesWithIndexContext<O>,
operations: Vec<MultipleAttributesWithIndexOperation<O>>,
}
impl<O: RootOperand> DeepClone for MultipleAttributesWithIndexOperand<O> {
fn deep_clone(&self) -> Self {
Self {
context: self.context.clone(),
operations: self.operations.iter().map(DeepClone::deep_clone).collect(),
}
}
}
impl<'a, O: 'a + RootOperand> EvaluateForward<'a> for MultipleAttributesWithIndexOperand<O> {
type InputValue = BoxedIterator<'a, (&'a O::Index, MedRecordAttribute)>;
type ReturnValue = BoxedIterator<'a, (&'a O::Index, MedRecordAttribute)>;
fn evaluate_forward(
&self,
medrecord: &'a MedRecord,
attributes: Self::InputValue,
) -> MedRecordResult<Self::ReturnValue> {
let attributes: BoxedIterator<_> = Box::new(attributes);
self.operations
.iter()
.try_fold(attributes, |attribute_tuples, operation| {
operation.evaluate(medrecord, attribute_tuples)
})
}
}
impl<'a, O: 'a + RootOperand> EvaluateForwardGrouped<'a> for MultipleAttributesWithIndexOperand<O> {
fn evaluate_forward_grouped(
&self,
medrecord: &'a MedRecord,
attributes: GroupedIterator<'a, Self::InputValue>,
) -> MedRecordResult<GroupedIterator<'a, Self::ReturnValue>> {
self.operations
.iter()
.try_fold(attributes, |attribute_tuples, operation| {
operation.evaluate_grouped(medrecord, attribute_tuples)
})
}
}
impl<'a, O: 'a + RootOperand> EvaluateBackward<'a> for MultipleAttributesWithIndexOperand<O> {
type ReturnValue = BoxedIterator<'a, (&'a O::Index, MedRecordAttribute)>;
fn evaluate_backward(&self, medrecord: &'a MedRecord) -> MedRecordResult<Self::ReturnValue> {
let attributes = self.context.get_attributes(medrecord)?;
self.evaluate_forward(medrecord, attributes)
}
}
impl<O: RootOperand> Max for MultipleAttributesWithIndexOperand<O> {
type ReturnOperand = SingleAttributeWithIndexOperand<O>;
fn max(&mut self) -> Wrapper<Self::ReturnOperand> {
let operand =
Wrapper::<Self::ReturnOperand>::new(self.deep_clone(), SingleKindWithIndex::Max);
self.operations.push(
MultipleAttributesWithIndexOperation::AttributeWithIndexOperation {
operand: operand.clone(),
},
);
operand
}
}
impl<O: RootOperand> Min for MultipleAttributesWithIndexOperand<O> {
type ReturnOperand = SingleAttributeWithIndexOperand<O>;
fn min(&mut self) -> Wrapper<Self::ReturnOperand> {
let operand =
Wrapper::<Self::ReturnOperand>::new(self.deep_clone(), SingleKindWithIndex::Min);
self.operations.push(
MultipleAttributesWithIndexOperation::AttributeWithIndexOperation {
operand: operand.clone(),
},
);
operand
}
}
impl<O: RootOperand> Count for MultipleAttributesWithIndexOperand<O> {
type ReturnOperand = SingleAttributeWithoutIndexOperand<O>;
fn count(&mut self) -> Wrapper<Self::ReturnOperand> {
let operand = Wrapper::<Self::ReturnOperand>::new(
SingleAttributeWithoutIndexContext::MultipleAttributesWithIndexOperand(
self.deep_clone(),
),
SingleKindWithoutIndex::Count,
);
self.operations.push(
MultipleAttributesWithIndexOperation::AttributeWithoutIndexOperation {
operand: operand.clone(),
},
);
operand
}
}
impl<O: RootOperand> Sum for MultipleAttributesWithIndexOperand<O> {
type ReturnOperand = SingleAttributeWithoutIndexOperand<O>;
fn sum(&mut self) -> Wrapper<Self::ReturnOperand> {
let operand = Wrapper::<Self::ReturnOperand>::new(
SingleAttributeWithoutIndexContext::MultipleAttributesWithIndexOperand(
self.deep_clone(),
),
SingleKindWithoutIndex::Sum,
);
self.operations.push(
MultipleAttributesWithIndexOperation::AttributeWithoutIndexOperation {
operand: operand.clone(),
},
);
operand
}
}
impl<O: RootOperand> Random for MultipleAttributesWithIndexOperand<O> {
type ReturnOperand = SingleAttributeWithIndexOperand<O>;
fn random(&mut self) -> Wrapper<Self::ReturnOperand> {
let operand =
Wrapper::<Self::ReturnOperand>::new(self.deep_clone(), SingleKindWithIndex::Random);
self.operations.push(
MultipleAttributesWithIndexOperation::AttributeWithIndexOperation {
operand: operand.clone(),
},
);
operand
}
}
impl<O: RootOperand> GreaterThan for MultipleAttributesWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn greater_than<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::GreaterThan,
},
);
}
}
impl<O: RootOperand> GreaterThanOrEqualTo for MultipleAttributesWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn greater_than_or_equal_to<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::GreaterThanOrEqualTo,
},
);
}
}
impl<O: RootOperand> LessThan for MultipleAttributesWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn less_than<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::LessThan,
},
);
}
}
impl<O: RootOperand> LessThanOrEqualTo for MultipleAttributesWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn less_than_or_equal_to<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::LessThanOrEqualTo,
},
);
}
}
impl<O: RootOperand> EqualTo for MultipleAttributesWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn equal_to<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::EqualTo,
},
);
}
}
impl<O: RootOperand> NotEqualTo for MultipleAttributesWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn not_equal_to<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::NotEqualTo,
},
);
}
}
impl<O: RootOperand> StartsWith for MultipleAttributesWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn starts_with<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::StartsWith,
},
);
}
}
impl<O: RootOperand> EndsWith for MultipleAttributesWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn ends_with<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::EndsWith,
},
);
}
}
impl<O: RootOperand> Contains for MultipleAttributesWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn contains<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::Contains,
},
);
}
}
impl<O: RootOperand> IsIn for MultipleAttributesWithIndexOperand<O> {
type ComparisonOperand = MultipleAttributesComparisonOperand;
fn is_in<V: Into<Self::ComparisonOperand>>(&mut self, values: V) {
self.operations.push(
MultipleAttributesWithIndexOperation::MultipleAttributesComparisonOperation {
operand: values.into(),
kind: MultipleComparisonKind::IsIn,
},
);
}
}
impl<O: RootOperand> IsNotIn for MultipleAttributesWithIndexOperand<O> {
type ComparisonOperand = MultipleAttributesComparisonOperand;
fn is_not_in<V: Into<Self::ComparisonOperand>>(&mut self, values: V) {
self.operations.push(
MultipleAttributesWithIndexOperation::MultipleAttributesComparisonOperation {
operand: values.into(),
kind: MultipleComparisonKind::IsNotIn,
},
);
}
}
impl<O: RootOperand> Add for MultipleAttributesWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn add<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithIndexOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Add,
},
);
}
}
impl<O: RootOperand> Sub for MultipleAttributesWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn sub<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithIndexOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Sub,
},
);
}
}
impl<O: RootOperand> Mul for MultipleAttributesWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn mul<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithIndexOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Mul,
},
);
}
}
impl<O: RootOperand> Pow for MultipleAttributesWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn pow<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithIndexOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Pow,
},
);
}
}
impl<O: RootOperand> Mod for MultipleAttributesWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn r#mod<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithIndexOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Mod,
},
);
}
}
impl<O: RootOperand> Abs for MultipleAttributesWithIndexOperand<O> {
fn abs(&mut self) {
self.operations.push(
MultipleAttributesWithIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::Abs,
},
);
}
}
impl<O: RootOperand> Trim for MultipleAttributesWithIndexOperand<O> {
fn trim(&mut self) {
self.operations.push(
MultipleAttributesWithIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::Trim,
},
);
}
}
impl<O: RootOperand> TrimStart for MultipleAttributesWithIndexOperand<O> {
fn trim_start(&mut self) {
self.operations.push(
MultipleAttributesWithIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::TrimStart,
},
);
}
}
impl<O: RootOperand> TrimEnd for MultipleAttributesWithIndexOperand<O> {
fn trim_end(&mut self) {
self.operations.push(
MultipleAttributesWithIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::TrimEnd,
},
);
}
}
impl<O: RootOperand> Lowercase for MultipleAttributesWithIndexOperand<O> {
fn lowercase(&mut self) {
self.operations.push(
MultipleAttributesWithIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::Lowercase,
},
);
}
}
impl<O: RootOperand> Uppercase for MultipleAttributesWithIndexOperand<O> {
fn uppercase(&mut self) {
self.operations.push(
MultipleAttributesWithIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::Uppercase,
},
);
}
}
impl<O: RootOperand> ToValues for MultipleAttributesWithIndexOperand<O> {
type ReturnOperand = MultipleValuesWithIndexOperand<O>;
fn to_values(&mut self) -> Wrapper<Self::ReturnOperand> {
let operand = Wrapper::<Self::ReturnOperand>::new(
MultipleValuesWithIndexContext::MultipleAttributesOperand(self.deep_clone()),
);
self.operations
.push(MultipleAttributesWithIndexOperation::ToValues {
operand: operand.clone(),
});
operand
}
}
impl<O: RootOperand> Slice for MultipleAttributesWithIndexOperand<O> {
fn slice(&mut self, start: usize, end: usize) {
self.operations
.push(MultipleAttributesWithIndexOperation::Slice(start..end));
}
}
impl<O: RootOperand> IsString for MultipleAttributesWithIndexOperand<O> {
fn is_string(&mut self) {
self.operations
.push(MultipleAttributesWithIndexOperation::IsString);
}
}
impl<O: RootOperand> IsInt for MultipleAttributesWithIndexOperand<O> {
fn is_int(&mut self) {
self.operations
.push(MultipleAttributesWithIndexOperation::IsInt);
}
}
impl<O: RootOperand> IsMax for MultipleAttributesWithIndexOperand<O> {
fn is_max(&mut self) {
self.operations
.push(MultipleAttributesWithIndexOperation::IsMax);
}
}
impl<O: RootOperand> IsMin for MultipleAttributesWithIndexOperand<O> {
fn is_min(&mut self) {
self.operations
.push(MultipleAttributesWithIndexOperation::IsMin);
}
}
impl<O: RootOperand> EitherOr for MultipleAttributesWithIndexOperand<O> {
type QueryOperand = Self;
fn either_or<EQ, OQ>(&mut self, either_query: EQ, or_query: OQ)
where
EQ: FnOnce(&mut Wrapper<Self::QueryOperand>),
OQ: FnOnce(&mut Wrapper<Self::QueryOperand>),
{
let mut either_operand = Wrapper::<Self::QueryOperand>::new(self.context.clone());
let mut or_operand = Wrapper::<Self::QueryOperand>::new(self.context.clone());
either_query(&mut either_operand);
or_query(&mut or_operand);
self.operations
.push(MultipleAttributesWithIndexOperation::EitherOr {
either: either_operand,
or: or_operand,
});
}
}
impl<O: RootOperand> Exclude for MultipleAttributesWithIndexOperand<O> {
type QueryOperand = Self;
fn exclude<Q>(&mut self, query: Q)
where
Q: FnOnce(&mut Wrapper<Self::QueryOperand>),
{
let mut operand = Wrapper::<Self::QueryOperand>::new(self.context.clone());
query(&mut operand);
self.operations
.push(MultipleAttributesWithIndexOperation::Exclude { operand });
}
}
impl<O: RootOperand> MultipleAttributesWithIndexOperand<O> {
pub(crate) fn new(context: MultipleAttributesWithIndexContext<O>) -> Self {
Self {
context,
operations: Vec::new(),
}
}
pub(crate) fn push_merge_operation(
&mut self,
operand: Wrapper<MultipleAttributesWithIndexOperand<O>>,
) {
self.operations
.push(MultipleAttributesWithIndexOperation::Merge { operand });
}
}
impl<O: RootOperand> Wrapper<MultipleAttributesWithIndexOperand<O>> {
pub(crate) fn new(context: MultipleAttributesWithIndexContext<O>) -> Self {
MultipleAttributesWithIndexOperand::new(context).into()
}
pub(crate) fn push_merge_operation(
&self,
operand: Wrapper<MultipleAttributesWithIndexOperand<O>>,
) {
self.0.write_or_panic().push_merge_operation(operand)
}
}
pub type NodeMultipleAttributesWithoutIndexOperand =
MultipleAttributesWithoutIndexOperand<NodeOperand>;
pub type EdgeMultipleAttributesWithoutIndexOperand =
MultipleAttributesWithoutIndexOperand<EdgeOperand>;
#[derive(Debug, Clone)]
pub struct MultipleAttributesWithoutIndexOperand<O: RootOperand> {
context: MultipleAttributesWithoutIndexContext<O>,
operations: Vec<MultipleAttributesWithoutIndexOperation<O>>,
}
impl<O: RootOperand> DeepClone for MultipleAttributesWithoutIndexOperand<O> {
fn deep_clone(&self) -> Self {
Self {
context: self.context.deep_clone(),
operations: self.operations.iter().map(DeepClone::deep_clone).collect(),
}
}
}
impl<'a, O: 'a + RootOperand> EvaluateForward<'a> for MultipleAttributesWithoutIndexOperand<O> {
type InputValue = BoxedIterator<'a, MedRecordAttribute>;
type ReturnValue = BoxedIterator<'a, MedRecordAttribute>;
fn evaluate_forward(
&self,
medrecord: &'a MedRecord,
attributes: Self::InputValue,
) -> MedRecordResult<Self::ReturnValue> {
let attributes: BoxedIterator<_> = Box::new(attributes);
self.operations
.iter()
.try_fold(attributes, |attribute_tuples, operation| {
operation.evaluate(medrecord, attribute_tuples)
})
}
}
impl<'a, O: 'a + RootOperand> EvaluateBackward<'a> for MultipleAttributesWithoutIndexOperand<O> {
type ReturnValue = BoxedIterator<'a, MedRecordAttribute>;
fn evaluate_backward(&self, medrecord: &'a MedRecord) -> MedRecordResult<Self::ReturnValue> {
let attributes = self.context.get_attributes(medrecord)?;
self.evaluate_forward(medrecord, attributes)
}
}
impl<O: RootOperand> Max for MultipleAttributesWithoutIndexOperand<O> {
type ReturnOperand = SingleAttributeWithoutIndexOperand<O>;
fn max(&mut self) -> Wrapper<Self::ReturnOperand> {
let operand = Wrapper::<Self::ReturnOperand>::new(
SingleAttributeWithoutIndexContext::MultipleAttributesWithoutIndexOperand(
self.deep_clone(),
),
SingleKindWithoutIndex::Max,
);
self.operations.push(
MultipleAttributesWithoutIndexOperation::AttributeOperation {
operand: operand.clone(),
},
);
operand
}
}
impl<O: RootOperand> Min for MultipleAttributesWithoutIndexOperand<O> {
type ReturnOperand = SingleAttributeWithoutIndexOperand<O>;
fn min(&mut self) -> Wrapper<Self::ReturnOperand> {
let operand = Wrapper::<Self::ReturnOperand>::new(
SingleAttributeWithoutIndexContext::MultipleAttributesWithoutIndexOperand(
self.deep_clone(),
),
SingleKindWithoutIndex::Min,
);
self.operations.push(
MultipleAttributesWithoutIndexOperation::AttributeOperation {
operand: operand.clone(),
},
);
operand
}
}
impl<O: RootOperand> Count for MultipleAttributesWithoutIndexOperand<O> {
type ReturnOperand = SingleAttributeWithoutIndexOperand<O>;
fn count(&mut self) -> Wrapper<Self::ReturnOperand> {
let operand = Wrapper::<Self::ReturnOperand>::new(
SingleAttributeWithoutIndexContext::MultipleAttributesWithoutIndexOperand(
self.deep_clone(),
),
SingleKindWithoutIndex::Count,
);
self.operations.push(
MultipleAttributesWithoutIndexOperation::AttributeOperation {
operand: operand.clone(),
},
);
operand
}
}
impl<O: RootOperand> Sum for MultipleAttributesWithoutIndexOperand<O> {
type ReturnOperand = SingleAttributeWithoutIndexOperand<O>;
fn sum(&mut self) -> Wrapper<Self::ReturnOperand> {
let operand = Wrapper::<Self::ReturnOperand>::new(
SingleAttributeWithoutIndexContext::MultipleAttributesWithoutIndexOperand(
self.deep_clone(),
),
SingleKindWithoutIndex::Sum,
);
self.operations.push(
MultipleAttributesWithoutIndexOperation::AttributeOperation {
operand: operand.clone(),
},
);
operand
}
}
impl<O: RootOperand> Random for MultipleAttributesWithoutIndexOperand<O> {
type ReturnOperand = SingleAttributeWithoutIndexOperand<O>;
fn random(&mut self) -> Wrapper<Self::ReturnOperand> {
let operand = Wrapper::<Self::ReturnOperand>::new(
SingleAttributeWithoutIndexContext::MultipleAttributesWithoutIndexOperand(
self.deep_clone(),
),
SingleKindWithoutIndex::Random,
);
self.operations.push(
MultipleAttributesWithoutIndexOperation::AttributeOperation {
operand: operand.clone(),
},
);
operand
}
}
impl<O: RootOperand> GreaterThan for MultipleAttributesWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn greater_than<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::GreaterThan,
},
);
}
}
impl<O: RootOperand> GreaterThanOrEqualTo for MultipleAttributesWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn greater_than_or_equal_to<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::GreaterThanOrEqualTo,
},
);
}
}
impl<O: RootOperand> LessThan for MultipleAttributesWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn less_than<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::LessThan,
},
);
}
}
impl<O: RootOperand> LessThanOrEqualTo for MultipleAttributesWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn less_than_or_equal_to<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::LessThanOrEqualTo,
},
);
}
}
impl<O: RootOperand> EqualTo for MultipleAttributesWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn equal_to<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::EqualTo,
},
);
}
}
impl<O: RootOperand> NotEqualTo for MultipleAttributesWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn not_equal_to<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::NotEqualTo,
},
);
}
}
impl<O: RootOperand> StartsWith for MultipleAttributesWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn starts_with<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::StartsWith,
},
);
}
}
impl<O: RootOperand> EndsWith for MultipleAttributesWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn ends_with<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::EndsWith,
},
);
}
}
impl<O: RootOperand> Contains for MultipleAttributesWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn contains<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::Contains,
},
);
}
}
impl<O: RootOperand> IsIn for MultipleAttributesWithoutIndexOperand<O> {
type ComparisonOperand = MultipleAttributesComparisonOperand;
fn is_in<V: Into<Self::ComparisonOperand>>(&mut self, values: V) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::MultipleAttributesComparisonOperation {
operand: values.into(),
kind: MultipleComparisonKind::IsIn,
},
);
}
}
impl<O: RootOperand> IsNotIn for MultipleAttributesWithoutIndexOperand<O> {
type ComparisonOperand = MultipleAttributesComparisonOperand;
fn is_not_in<V: Into<Self::ComparisonOperand>>(&mut self, values: V) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::MultipleAttributesComparisonOperation {
operand: values.into(),
kind: MultipleComparisonKind::IsNotIn,
},
);
}
}
impl<O: RootOperand> Add for MultipleAttributesWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn add<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Add,
},
);
}
}
impl<O: RootOperand> Sub for MultipleAttributesWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn sub<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Sub,
},
);
}
}
impl<O: RootOperand> Mul for MultipleAttributesWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn mul<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Mul,
},
);
}
}
impl<O: RootOperand> Pow for MultipleAttributesWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn pow<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Pow,
},
);
}
}
impl<O: RootOperand> Mod for MultipleAttributesWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn r#mod<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Mod,
},
);
}
}
impl<O: RootOperand> Abs for MultipleAttributesWithoutIndexOperand<O> {
fn abs(&mut self) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::Abs,
},
);
}
}
impl<O: RootOperand> Trim for MultipleAttributesWithoutIndexOperand<O> {
fn trim(&mut self) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::Trim,
},
);
}
}
impl<O: RootOperand> TrimStart for MultipleAttributesWithoutIndexOperand<O> {
fn trim_start(&mut self) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::TrimStart,
},
);
}
}
impl<O: RootOperand> TrimEnd for MultipleAttributesWithoutIndexOperand<O> {
fn trim_end(&mut self) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::TrimEnd,
},
);
}
}
impl<O: RootOperand> Lowercase for MultipleAttributesWithoutIndexOperand<O> {
fn lowercase(&mut self) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::Lowercase,
},
);
}
}
impl<O: RootOperand> Uppercase for MultipleAttributesWithoutIndexOperand<O> {
fn uppercase(&mut self) {
self.operations.push(
MultipleAttributesWithoutIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::Uppercase,
},
);
}
}
impl<O: RootOperand> Slice for MultipleAttributesWithoutIndexOperand<O> {
fn slice(&mut self, start: usize, end: usize) {
self.operations
.push(MultipleAttributesWithoutIndexOperation::Slice(start..end));
}
}
impl<O: RootOperand> IsString for MultipleAttributesWithoutIndexOperand<O> {
fn is_string(&mut self) {
self.operations
.push(MultipleAttributesWithoutIndexOperation::IsString);
}
}
impl<O: RootOperand> IsInt for MultipleAttributesWithoutIndexOperand<O> {
fn is_int(&mut self) {
self.operations
.push(MultipleAttributesWithoutIndexOperation::IsInt);
}
}
impl<O: RootOperand> IsMax for MultipleAttributesWithoutIndexOperand<O> {
fn is_max(&mut self) {
self.operations
.push(MultipleAttributesWithoutIndexOperation::IsMax);
}
}
impl<O: RootOperand> IsMin for MultipleAttributesWithoutIndexOperand<O> {
fn is_min(&mut self) {
self.operations
.push(MultipleAttributesWithoutIndexOperation::IsMin);
}
}
impl<O: RootOperand> EitherOr for MultipleAttributesWithoutIndexOperand<O> {
type QueryOperand = Self;
fn either_or<EQ, OQ>(&mut self, either_query: EQ, or_query: OQ)
where
EQ: FnOnce(&mut Wrapper<Self::QueryOperand>),
OQ: FnOnce(&mut Wrapper<Self::QueryOperand>),
{
let mut either_operand = Wrapper::<Self::QueryOperand>::new(self.context.clone());
let mut or_operand = Wrapper::<Self::QueryOperand>::new(self.context.clone());
either_query(&mut either_operand);
or_query(&mut or_operand);
self.operations
.push(MultipleAttributesWithoutIndexOperation::EitherOr {
either: either_operand,
or: or_operand,
});
}
}
impl<O: RootOperand> Exclude for MultipleAttributesWithoutIndexOperand<O> {
type QueryOperand = Self;
fn exclude<Q>(&mut self, query: Q)
where
Q: FnOnce(&mut Wrapper<Self::QueryOperand>),
{
let mut operand = Wrapper::<Self::QueryOperand>::new(self.context.clone());
query(&mut operand);
self.operations
.push(MultipleAttributesWithoutIndexOperation::Exclude { operand });
}
}
impl<O: RootOperand> MultipleAttributesWithoutIndexOperand<O> {
pub(crate) fn new(context: MultipleAttributesWithoutIndexContext<O>) -> Self {
Self {
context,
operations: Vec::new(),
}
}
}
impl<O: RootOperand> Wrapper<MultipleAttributesWithoutIndexOperand<O>> {
pub(crate) fn new(context: MultipleAttributesWithoutIndexContext<O>) -> Self {
MultipleAttributesWithoutIndexOperand::new(context).into()
}
}
pub type NodeSingleAttributeWithIndexOperand = SingleAttributeWithIndexOperand<NodeOperand>;
pub type EdgeSingleAttributeWithIndexOperand = SingleAttributeWithIndexOperand<EdgeOperand>;
#[derive(Debug, Clone)]
pub struct SingleAttributeWithIndexOperand<O: RootOperand> {
context: MultipleAttributesWithIndexOperand<O>,
pub(crate) kind: SingleKindWithIndex,
operations: Vec<SingleAttributeWithIndexOperation<O>>,
}
impl<O: RootOperand> DeepClone for SingleAttributeWithIndexOperand<O> {
fn deep_clone(&self) -> Self {
Self {
context: self.context.deep_clone(),
kind: self.kind.clone(),
operations: self.operations.iter().map(DeepClone::deep_clone).collect(),
}
}
}
impl<'a, O: 'a + RootOperand> EvaluateForward<'a> for SingleAttributeWithIndexOperand<O> {
type InputValue = Option<(&'a O::Index, MedRecordAttribute)>;
type ReturnValue = Option<(&'a O::Index, MedRecordAttribute)>;
fn evaluate_forward(
&self,
medrecord: &'a MedRecord,
attribute: Self::InputValue,
) -> MedRecordResult<Self::ReturnValue> {
self.operations
.iter()
.try_fold(attribute, |attribute, operation| {
operation.evaluate(medrecord, attribute)
})
}
}
impl<'a, O: 'a + RootOperand> EvaluateForwardGrouped<'a> for SingleAttributeWithIndexOperand<O> {
fn evaluate_forward_grouped(
&self,
medrecord: &'a MedRecord,
attributes: GroupedIterator<'a, Self::InputValue>,
) -> MedRecordResult<GroupedIterator<'a, Self::ReturnValue>> {
self.operations
.iter()
.try_fold(attributes, |attributes, operation| {
operation.evaluate_grouped(medrecord, attributes)
})
}
}
impl<'a, O: 'a + RootOperand> EvaluateBackward<'a> for SingleAttributeWithIndexOperand<O> {
type ReturnValue = <Self as EvaluateForward<'a>>::ReturnValue;
fn evaluate_backward(&self, medrecord: &'a MedRecord) -> MedRecordResult<Self::ReturnValue> {
let attributes = self.context.evaluate_backward(medrecord)?;
let attribute = self.reduce_input(attributes)?;
self.evaluate_forward(medrecord, attribute)
}
}
impl<'a, O: 'a + RootOperand> ReduceInput<'a> for SingleAttributeWithIndexOperand<O> {
type Context = MultipleAttributesWithIndexOperand<O>;
#[inline]
fn reduce_input(
&self,
attributes: <Self::Context as EvaluateBackward<'a>>::ReturnValue,
) -> MedRecordResult<<Self as EvaluateForward<'a>>::InputValue> {
Ok(match self.kind {
SingleKindWithIndex::Max => {
MultipleAttributesWithIndexOperation::<O>::get_max(attributes)?
}
SingleKindWithIndex::Min => {
MultipleAttributesWithIndexOperation::<O>::get_min(attributes)?
}
SingleKindWithIndex::Random => {
MultipleAttributesWithIndexOperation::<O>::get_random(attributes)
}
})
}
}
impl<O: RootOperand> GreaterThan for SingleAttributeWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn greater_than<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::GreaterThan,
},
);
}
}
impl<O: RootOperand> GreaterThanOrEqualTo for SingleAttributeWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn greater_than_or_equal_to<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::GreaterThanOrEqualTo,
},
);
}
}
impl<O: RootOperand> LessThan for SingleAttributeWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn less_than<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::LessThan,
},
);
}
}
impl<O: RootOperand> LessThanOrEqualTo for SingleAttributeWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn less_than_or_equal_to<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::LessThanOrEqualTo,
},
);
}
}
impl<O: RootOperand> EqualTo for SingleAttributeWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn equal_to<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::EqualTo,
},
);
}
}
impl<O: RootOperand> NotEqualTo for SingleAttributeWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn not_equal_to<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::NotEqualTo,
},
);
}
}
impl<O: RootOperand> StartsWith for SingleAttributeWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn starts_with<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::StartsWith,
},
);
}
}
impl<O: RootOperand> EndsWith for SingleAttributeWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn ends_with<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::EndsWith,
},
);
}
}
impl<O: RootOperand> Contains for SingleAttributeWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn contains<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::Contains,
},
);
}
}
impl<O: RootOperand> IsIn for SingleAttributeWithIndexOperand<O> {
type ComparisonOperand = MultipleAttributesComparisonOperand;
fn is_in<V: Into<Self::ComparisonOperand>>(&mut self, attributes: V) {
self.operations.push(
SingleAttributeWithIndexOperation::MultipleAttributesComparisonOperation {
operand: attributes.into(),
kind: MultipleComparisonKind::IsIn,
},
);
}
}
impl<O: RootOperand> IsNotIn for SingleAttributeWithIndexOperand<O> {
type ComparisonOperand = MultipleAttributesComparisonOperand;
fn is_not_in<V: Into<Self::ComparisonOperand>>(&mut self, attributes: V) {
self.operations.push(
SingleAttributeWithIndexOperation::MultipleAttributesComparisonOperation {
operand: attributes.into(),
kind: MultipleComparisonKind::IsNotIn,
},
);
}
}
impl<O: RootOperand> Add for SingleAttributeWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn add<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithIndexOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Add,
},
);
}
}
impl<O: RootOperand> Sub for SingleAttributeWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn sub<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithIndexOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Sub,
},
);
}
}
impl<O: RootOperand> Mul for SingleAttributeWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn mul<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithIndexOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Mul,
},
);
}
}
impl<O: RootOperand> Pow for SingleAttributeWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn pow<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithIndexOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Pow,
},
);
}
}
impl<O: RootOperand> Mod for SingleAttributeWithIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn r#mod<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithIndexOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Mod,
},
);
}
}
impl<O: RootOperand> Abs for SingleAttributeWithIndexOperand<O> {
fn abs(&mut self) {
self.operations.push(
SingleAttributeWithIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::Abs,
},
);
}
}
impl<O: RootOperand> Trim for SingleAttributeWithIndexOperand<O> {
fn trim(&mut self) {
self.operations.push(
SingleAttributeWithIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::Trim,
},
);
}
}
impl<O: RootOperand> TrimStart for SingleAttributeWithIndexOperand<O> {
fn trim_start(&mut self) {
self.operations.push(
SingleAttributeWithIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::TrimStart,
},
);
}
}
impl<O: RootOperand> TrimEnd for SingleAttributeWithIndexOperand<O> {
fn trim_end(&mut self) {
self.operations.push(
SingleAttributeWithIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::TrimEnd,
},
);
}
}
impl<O: RootOperand> Lowercase for SingleAttributeWithIndexOperand<O> {
fn lowercase(&mut self) {
self.operations.push(
SingleAttributeWithIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::Lowercase,
},
);
}
}
impl<O: RootOperand> Uppercase for SingleAttributeWithIndexOperand<O> {
fn uppercase(&mut self) {
self.operations.push(
SingleAttributeWithIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::Uppercase,
},
);
}
}
impl<O: RootOperand> Slice for SingleAttributeWithIndexOperand<O> {
fn slice(&mut self, start: usize, end: usize) {
self.operations
.push(SingleAttributeWithIndexOperation::Slice(start..end));
}
}
impl<O: RootOperand> IsString for SingleAttributeWithIndexOperand<O> {
fn is_string(&mut self) {
self.operations
.push(SingleAttributeWithIndexOperation::IsString);
}
}
impl<O: RootOperand> IsInt for SingleAttributeWithIndexOperand<O> {
fn is_int(&mut self) {
self.operations
.push(SingleAttributeWithIndexOperation::IsInt);
}
}
impl<O: RootOperand> EitherOr for SingleAttributeWithIndexOperand<O> {
type QueryOperand = Self;
fn either_or<EQ, OQ>(&mut self, either_query: EQ, or_query: OQ)
where
EQ: FnOnce(&mut Wrapper<Self::QueryOperand>),
OQ: FnOnce(&mut Wrapper<Self::QueryOperand>),
{
let mut either_operand =
Wrapper::<Self::QueryOperand>::new(self.context.clone(), self.kind.clone());
let mut or_operand =
Wrapper::<Self::QueryOperand>::new(self.context.clone(), self.kind.clone());
either_query(&mut either_operand);
or_query(&mut or_operand);
self.operations
.push(SingleAttributeWithIndexOperation::EitherOr {
either: either_operand,
or: or_operand,
});
}
}
impl<O: RootOperand> Exclude for SingleAttributeWithIndexOperand<O> {
type QueryOperand = Self;
fn exclude<Q>(&mut self, query: Q)
where
Q: FnOnce(&mut Wrapper<Self::QueryOperand>),
{
let mut operand =
Wrapper::<Self::QueryOperand>::new(self.context.clone(), self.kind.clone());
query(&mut operand);
self.operations
.push(SingleAttributeWithIndexOperation::Exclude { operand });
}
}
impl<O: RootOperand> SingleAttributeWithIndexOperand<O> {
pub(crate) fn new(
context: MultipleAttributesWithIndexOperand<O>,
kind: SingleKindWithIndex,
) -> Self {
Self {
context,
kind,
operations: Vec::new(),
}
}
pub(crate) fn push_merge_operation(
&mut self,
operand: Wrapper<MultipleAttributesWithIndexOperand<O>>,
) {
self.operations
.push(SingleAttributeWithIndexOperation::Merge { operand });
}
}
impl<O: RootOperand> Wrapper<SingleAttributeWithIndexOperand<O>> {
pub(crate) fn new(
context: MultipleAttributesWithIndexOperand<O>,
kind: SingleKindWithIndex,
) -> Self {
SingleAttributeWithIndexOperand::new(context, kind).into()
}
pub(crate) fn push_merge_operation(
&self,
operand: Wrapper<MultipleAttributesWithIndexOperand<O>>,
) {
self.0.write_or_panic().push_merge_operation(operand)
}
}
pub type NodeSingleAttributeWithoutIndexOperand = SingleAttributeWithoutIndexOperand<NodeOperand>;
pub type EdgeSingleAttributeWithoutIndexOperand = SingleAttributeWithoutIndexOperand<EdgeOperand>;
#[derive(Debug, Clone)]
pub struct SingleAttributeWithoutIndexOperand<O: RootOperand> {
context: SingleAttributeWithoutIndexContext<O>,
pub(crate) kind: SingleKindWithoutIndex,
operations: Vec<SingleAttributeWithoutIndexOperation<O>>,
}
impl<O: RootOperand> DeepClone for SingleAttributeWithoutIndexOperand<O> {
fn deep_clone(&self) -> Self {
Self {
context: self.context.deep_clone(),
kind: self.kind.clone(),
operations: self.operations.iter().map(DeepClone::deep_clone).collect(),
}
}
}
impl<'a, O: 'a + RootOperand> EvaluateForward<'a> for SingleAttributeWithoutIndexOperand<O> {
type InputValue = Option<MedRecordAttribute>;
type ReturnValue = Option<MedRecordAttribute>;
fn evaluate_forward(
&self,
medrecord: &'a MedRecord,
attribute: Self::InputValue,
) -> MedRecordResult<Self::ReturnValue> {
self.operations
.iter()
.try_fold(attribute, |attribute, operation| {
operation.evaluate(medrecord, attribute)
})
}
}
impl<'a, O: 'a + RootOperand> EvaluateForwardGrouped<'a> for SingleAttributeWithoutIndexOperand<O> {
fn evaluate_forward_grouped(
&self,
medrecord: &'a MedRecord,
attributes: GroupedIterator<'a, Self::InputValue>,
) -> MedRecordResult<GroupedIterator<'a, Self::ReturnValue>> {
self.operations
.iter()
.try_fold(attributes, |attributes, operation| {
operation.evaluate_grouped(medrecord, attributes)
})
}
}
impl<'a, O: 'a + RootOperand> EvaluateBackward<'a> for SingleAttributeWithoutIndexOperand<O> {
type ReturnValue = <Self as EvaluateForward<'a>>::ReturnValue;
fn evaluate_backward(&self, medrecord: &'a MedRecord) -> MedRecordResult<Self::ReturnValue> {
let attributes = self.context.get_attributes(medrecord)?;
let attribute = match self.kind {
SingleKindWithoutIndex::Max => {
MultipleAttributesWithoutIndexOperation::<O>::get_max(attributes)?
}
SingleKindWithoutIndex::Min => {
MultipleAttributesWithoutIndexOperation::<O>::get_min(attributes)?
}
SingleKindWithoutIndex::Count => Some(
MultipleAttributesWithoutIndexOperation::<O>::get_count(attributes),
),
SingleKindWithoutIndex::Sum => {
MultipleAttributesWithoutIndexOperation::<O>::get_sum(attributes)?
}
SingleKindWithoutIndex::Random => {
MultipleAttributesWithoutIndexOperation::<O>::get_random(attributes)
}
};
self.evaluate_forward(medrecord, attribute)
}
}
impl<O: RootOperand> GreaterThan for SingleAttributeWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn greater_than<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithoutIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::GreaterThan,
},
);
}
}
impl<O: RootOperand> GreaterThanOrEqualTo for SingleAttributeWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn greater_than_or_equal_to<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithoutIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::GreaterThanOrEqualTo,
},
);
}
}
impl<O: RootOperand> LessThan for SingleAttributeWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn less_than<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithoutIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::LessThan,
},
);
}
}
impl<O: RootOperand> LessThanOrEqualTo for SingleAttributeWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn less_than_or_equal_to<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithoutIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::LessThanOrEqualTo,
},
);
}
}
impl<O: RootOperand> EqualTo for SingleAttributeWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn equal_to<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithoutIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::EqualTo,
},
);
}
}
impl<O: RootOperand> NotEqualTo for SingleAttributeWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn not_equal_to<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithoutIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::NotEqualTo,
},
);
}
}
impl<O: RootOperand> StartsWith for SingleAttributeWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn starts_with<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithoutIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::StartsWith,
},
);
}
}
impl<O: RootOperand> EndsWith for SingleAttributeWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn ends_with<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithoutIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::EndsWith,
},
);
}
}
impl<O: RootOperand> Contains for SingleAttributeWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn contains<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithoutIndexOperation::SingleAttributeComparisonOperation {
operand: value.into(),
kind: SingleComparisonKind::Contains,
},
);
}
}
impl<O: RootOperand> IsIn for SingleAttributeWithoutIndexOperand<O> {
type ComparisonOperand = MultipleAttributesComparisonOperand;
fn is_in<V: Into<Self::ComparisonOperand>>(&mut self, attributes: V) {
self.operations.push(
SingleAttributeWithoutIndexOperation::MultipleAttributesComparisonOperation {
operand: attributes.into(),
kind: MultipleComparisonKind::IsIn,
},
);
}
}
impl<O: RootOperand> IsNotIn for SingleAttributeWithoutIndexOperand<O> {
type ComparisonOperand = MultipleAttributesComparisonOperand;
fn is_not_in<V: Into<Self::ComparisonOperand>>(&mut self, attributes: V) {
self.operations.push(
SingleAttributeWithoutIndexOperation::MultipleAttributesComparisonOperation {
operand: attributes.into(),
kind: MultipleComparisonKind::IsNotIn,
},
);
}
}
impl<O: RootOperand> Add for SingleAttributeWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn add<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithoutIndexOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Add,
},
);
}
}
impl<O: RootOperand> Sub for SingleAttributeWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn sub<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithoutIndexOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Sub,
},
);
}
}
impl<O: RootOperand> Mul for SingleAttributeWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn mul<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithoutIndexOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Mul,
},
);
}
}
impl<O: RootOperand> Pow for SingleAttributeWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn pow<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithoutIndexOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Pow,
},
);
}
}
impl<O: RootOperand> Mod for SingleAttributeWithoutIndexOperand<O> {
type ComparisonOperand = SingleAttributeComparisonOperand;
fn r#mod<V: Into<Self::ComparisonOperand>>(&mut self, value: V) {
self.operations.push(
SingleAttributeWithoutIndexOperation::BinaryArithmeticOperation {
operand: value.into(),
kind: BinaryArithmeticKind::Mod,
},
);
}
}
impl<O: RootOperand> Abs for SingleAttributeWithoutIndexOperand<O> {
fn abs(&mut self) {
self.operations.push(
SingleAttributeWithoutIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::Abs,
},
);
}
}
impl<O: RootOperand> Trim for SingleAttributeWithoutIndexOperand<O> {
fn trim(&mut self) {
self.operations.push(
SingleAttributeWithoutIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::Trim,
},
);
}
}
impl<O: RootOperand> TrimStart for SingleAttributeWithoutIndexOperand<O> {
fn trim_start(&mut self) {
self.operations.push(
SingleAttributeWithoutIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::TrimStart,
},
);
}
}
impl<O: RootOperand> TrimEnd for SingleAttributeWithoutIndexOperand<O> {
fn trim_end(&mut self) {
self.operations.push(
SingleAttributeWithoutIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::TrimEnd,
},
);
}
}
impl<O: RootOperand> Lowercase for SingleAttributeWithoutIndexOperand<O> {
fn lowercase(&mut self) {
self.operations.push(
SingleAttributeWithoutIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::Lowercase,
},
);
}
}
impl<O: RootOperand> Uppercase for SingleAttributeWithoutIndexOperand<O> {
fn uppercase(&mut self) {
self.operations.push(
SingleAttributeWithoutIndexOperation::UnaryArithmeticOperation {
kind: UnaryArithmeticKind::Uppercase,
},
);
}
}
impl<O: RootOperand> Slice for SingleAttributeWithoutIndexOperand<O> {
fn slice(&mut self, start: usize, end: usize) {
self.operations
.push(SingleAttributeWithoutIndexOperation::Slice(start..end));
}
}
impl<O: RootOperand> IsString for SingleAttributeWithoutIndexOperand<O> {
fn is_string(&mut self) {
self.operations
.push(SingleAttributeWithoutIndexOperation::IsString);
}
}
impl<O: RootOperand> IsInt for SingleAttributeWithoutIndexOperand<O> {
fn is_int(&mut self) {
self.operations
.push(SingleAttributeWithoutIndexOperation::IsInt);
}
}
impl<O: RootOperand> EitherOr for SingleAttributeWithoutIndexOperand<O> {
type QueryOperand = Self;
fn either_or<EQ, OQ>(&mut self, either_query: EQ, or_query: OQ)
where
EQ: FnOnce(&mut Wrapper<Self::QueryOperand>),
OQ: FnOnce(&mut Wrapper<Self::QueryOperand>),
{
let mut either_operand =
Wrapper::<Self::QueryOperand>::new(self.context.clone(), self.kind.clone());
let mut or_operand =
Wrapper::<Self::QueryOperand>::new(self.context.clone(), self.kind.clone());
either_query(&mut either_operand);
or_query(&mut or_operand);
self.operations
.push(SingleAttributeWithoutIndexOperation::EitherOr {
either: either_operand,
or: or_operand,
});
}
}
impl<O: RootOperand> Exclude for SingleAttributeWithoutIndexOperand<O> {
type QueryOperand = Self;
fn exclude<Q>(&mut self, query: Q)
where
Q: FnOnce(&mut Wrapper<Self::QueryOperand>),
{
let mut operand =
Wrapper::<Self::QueryOperand>::new(self.context.clone(), self.kind.clone());
query(&mut operand);
self.operations
.push(SingleAttributeWithoutIndexOperation::Exclude { operand });
}
}
impl<O: RootOperand> SingleAttributeWithoutIndexOperand<O> {
pub(crate) fn new(
context: SingleAttributeWithoutIndexContext<O>,
kind: SingleKindWithoutIndex,
) -> Self {
Self {
context,
kind,
operations: Vec::new(),
}
}
pub(crate) fn push_merge_operation(
&mut self,
operand: Wrapper<MultipleAttributesWithoutIndexOperand<O>>,
) {
self.operations
.push(SingleAttributeWithoutIndexOperation::Merge { operand });
}
}
impl<O: RootOperand> Wrapper<SingleAttributeWithoutIndexOperand<O>> {
pub(crate) fn new(
context: SingleAttributeWithoutIndexContext<O>,
kind: SingleKindWithoutIndex,
) -> Self {
SingleAttributeWithoutIndexOperand::new(context, kind).into()
}
pub(crate) fn push_merge_operation(
&self,
operand: Wrapper<MultipleAttributesWithoutIndexOperand<O>>,
) {
self.0.write_or_panic().push_merge_operation(operand)
}
}