drasi_core/evaluation/functions/aggregation/
last.rs1use std::{fmt::Debug, sync::Arc};
16
17use crate::{
18 evaluation::{FunctionError, FunctionEvaluationError},
19 interface::ResultIndex,
20 models::ElementValue,
21};
22
23use async_trait::async_trait;
24
25use drasi_query_ast::ast;
26
27use crate::evaluation::{variable_value::VariableValue, ExpressionEvaluationContext};
28
29use super::{super::AggregatingFunction, Accumulator, ValueAccumulator};
30
31pub struct Last {}
32
33#[async_trait]
34impl AggregatingFunction for Last {
35 fn initialize_accumulator(
36 &self,
37 _context: &ExpressionEvaluationContext,
38 _expression: &ast::FunctionExpression,
39 _grouping_keys: &Vec<VariableValue>,
40 _index: Arc<dyn ResultIndex>,
41 ) -> Accumulator {
42 Accumulator::Value(ValueAccumulator::Value(ElementValue::Null))
43 }
44
45 fn accumulator_is_lazy(&self) -> bool {
46 false
47 }
48
49 async fn apply(
50 &self,
51 _context: &ExpressionEvaluationContext,
52 args: Vec<VariableValue>,
53 accumulator: &mut Accumulator,
54 ) -> Result<VariableValue, FunctionError> {
55 if args.len() != 1 {
56 return Err(FunctionError {
57 function_name: "Last".to_string(),
58 error: FunctionEvaluationError::InvalidArgumentCount,
59 });
60 }
61
62 let value = match accumulator {
63 Accumulator::Value(super::ValueAccumulator::Value(value)) => value,
64 _ => {
65 return Err(FunctionError {
66 function_name: "Last".to_string(),
67 error: FunctionEvaluationError::CorruptData,
68 });
69 }
70 };
71
72 *value = match (&args[0]).try_into() {
73 Ok(value) => value,
74 Err(_) => {
75 return Err(FunctionError {
76 function_name: "Last".to_string(),
77 error: FunctionEvaluationError::InvalidType {
78 expected: "ElementValue".to_string(),
79 },
80 })
81 }
82 };
83
84 Ok((&value.clone()).into())
85 }
86
87 async fn revert(
88 &self,
89 _context: &ExpressionEvaluationContext,
90 args: Vec<VariableValue>,
91 accumulator: &mut Accumulator,
92 ) -> Result<VariableValue, FunctionError> {
93 if args.len() != 1 {
94 return Err(FunctionError {
95 function_name: "Last".to_string(),
96 error: FunctionEvaluationError::InvalidArgumentCount,
97 });
98 }
99 let value = match accumulator {
100 Accumulator::Value(super::ValueAccumulator::Value(value)) => value,
101 _ => {
102 return Err(FunctionError {
103 function_name: "Last".to_string(),
104 error: FunctionEvaluationError::CorruptData,
105 })
106 }
107 };
108
109 *value = ElementValue::Null;
110 Ok(VariableValue::Null)
111 }
112
113 async fn snapshot(
114 &self,
115 _context: &ExpressionEvaluationContext,
116 _args: Vec<VariableValue>,
117 accumulator: &Accumulator,
118 ) -> Result<VariableValue, FunctionError> {
119 let value = match accumulator {
120 Accumulator::Value(super::ValueAccumulator::Value(value)) => value,
121 _ => {
122 return Err(FunctionError {
123 function_name: "Last".to_string(),
124 error: FunctionEvaluationError::CorruptData,
125 })
126 }
127 };
128 Ok((&value.clone()).into())
129 }
130}
131
132impl Debug for Last {
133 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
134 write!(f, "Last")
135 }
136}