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