drasi_core/evaluation/functions/
metadata.rs

1// Copyright 2024 The Drasi Authors.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::sync::Arc;
16
17use crate::evaluation::variable_value::{zoned_datetime::ZonedDateTime, VariableValue};
18use async_trait::async_trait;
19use drasi_query_ast::ast;
20
21use crate::evaluation::{ExpressionEvaluationContext, FunctionError, FunctionEvaluationError};
22
23use super::{Function, FunctionRegistry, ScalarFunction};
24
25pub trait RegisterMetadataFunctions {
26    fn register_metadata_functions(&self);
27}
28
29impl RegisterMetadataFunctions for FunctionRegistry {
30    fn register_metadata_functions(&self) {
31        self.register_function("elementId", Function::Scalar(Arc::new(ElementId {})));
32        self.register_function(
33            "drasi.changeDateTime",
34            Function::Scalar(Arc::new(ChangeDateTime {})),
35        );
36    }
37}
38
39#[derive(Debug)]
40pub struct ElementId {}
41
42#[async_trait]
43impl ScalarFunction for ElementId {
44    async fn call(
45        &self,
46        _context: &ExpressionEvaluationContext,
47        expression: &ast::FunctionExpression,
48        args: Vec<VariableValue>,
49    ) -> Result<VariableValue, FunctionError> {
50        if args.len() != 1 {
51            return Err(FunctionError {
52                function_name: expression.name.to_string(),
53                error: FunctionEvaluationError::InvalidArgumentCount,
54            });
55        }
56        match &args[0] {
57            VariableValue::Element(e) => Ok(VariableValue::String(
58                e.get_reference().element_id.to_string(),
59            )),
60            _ => Err(FunctionError {
61                function_name: expression.name.to_string(),
62                error: FunctionEvaluationError::InvalidArgument(0),
63            }),
64        }
65    }
66}
67
68#[derive(Debug)]
69pub struct ChangeDateTime {}
70
71#[async_trait]
72impl ScalarFunction for ChangeDateTime {
73    async fn call(
74        &self,
75        _context: &ExpressionEvaluationContext,
76        expression: &ast::FunctionExpression,
77        args: Vec<VariableValue>,
78    ) -> Result<VariableValue, FunctionError> {
79        if args.len() != 1 {
80            return Err(FunctionError {
81                function_name: expression.name.to_string(),
82                error: FunctionEvaluationError::InvalidArgumentCount,
83            });
84        }
85        match &args[0] {
86            VariableValue::Element(e) => Ok(VariableValue::ZonedDateTime(
87                ZonedDateTime::from_epoch_millis(e.get_effective_from()),
88            )),
89            _ => Err(FunctionError {
90                function_name: expression.name.to_string(),
91                error: FunctionEvaluationError::InvalidArgument(0),
92            }),
93        }
94    }
95}