drasi_core/evaluation/functions/numeric/
ceil.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 async_trait::async_trait;
16use drasi_query_ast::ast;
17
18use crate::evaluation::functions::ScalarFunction;
19use crate::evaluation::variable_value::float::Float;
20use crate::evaluation::variable_value::VariableValue;
21use crate::evaluation::{ExpressionEvaluationContext, FunctionError, FunctionEvaluationError};
22
23#[derive(Debug)]
24pub struct Ceil {}
25
26#[async_trait]
27impl ScalarFunction for Ceil {
28    async fn call(
29        &self,
30        _context: &ExpressionEvaluationContext,
31        expression: &ast::FunctionExpression,
32        args: Vec<VariableValue>,
33    ) -> Result<VariableValue, FunctionError> {
34        if args.len() != 1 {
35            return Err(FunctionError {
36                function_name: expression.name.to_string(),
37                error: FunctionEvaluationError::InvalidArgumentCount,
38            });
39        }
40        match &args[0] {
41            VariableValue::Null => Ok(VariableValue::Null),
42            VariableValue::Integer(n) => Ok(VariableValue::Float(
43                match Float::from_f64(match n.as_i64() {
44                    Some(n) => n as f64,
45                    None => {
46                        return Err(FunctionError {
47                            function_name: expression.name.to_string(),
48                            error: FunctionEvaluationError::OverflowError,
49                        })
50                    }
51                }) {
52                    Some(n) => n,
53                    None => {
54                        return Err(FunctionError {
55                            function_name: expression.name.to_string(),
56                            error: FunctionEvaluationError::OverflowError,
57                        })
58                    }
59                },
60            )),
61            VariableValue::Float(n) => Ok(VariableValue::Float(
62                match Float::from_f64(match n.as_f64() {
63                    Some(n) => n.ceil(),
64                    None => {
65                        return Err(FunctionError {
66                            function_name: expression.name.to_string(),
67                            error: FunctionEvaluationError::OverflowError,
68                        })
69                    }
70                }) {
71                    Some(n) => n,
72                    None => {
73                        return Err(FunctionError {
74                            function_name: expression.name.to_string(),
75                            error: FunctionEvaluationError::OverflowError,
76                        })
77                    }
78                },
79            )),
80            _ => Err(FunctionError {
81                function_name: expression.name.to_string(),
82                error: FunctionEvaluationError::InvalidArgument(0),
83            }),
84        }
85    }
86}