drasi_core/evaluation/
mod.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
15mod expressions;
16
17pub mod context;
18pub mod functions;
19pub mod instant_query_clock;
20pub mod parts;
21pub mod temporal_constants;
22pub mod variable_value;
23
24use std::{
25    error::Error,
26    fmt::{self, Display},
27};
28
29pub use context::ExpressionEvaluationContext;
30pub use expressions::*;
31pub use instant_query_clock::InstantQueryClock;
32pub use parts::*;
33
34use crate::interface::{IndexError, MiddlewareError};
35
36#[derive(Debug)]
37pub enum EvaluationError {
38    DivideByZero,
39    InvalidType { expected: String },
40    UnknownIdentifier(String),
41    UnknownFunction(String), // Unknown Cypher function
42    IndexError(IndexError),
43    MiddlewareError(MiddlewareError),
44    ParseError,
45    InvalidContext,
46    OutOfRange { kind: OutOfRangeType },
47    OverflowError,
48    FunctionError(FunctionError),
49    CorruptData,
50    InvalidArgument,
51    UnknownProperty { property_name: String },
52}
53
54#[derive(Debug)]
55pub struct FunctionError {
56    function_name: String,
57    error: FunctionEvaluationError,
58}
59
60impl PartialEq for FunctionError {
61    fn eq(&self, other: &Self) -> bool {
62        self.error == other.error
63    }
64}
65
66#[derive(Debug)]
67pub enum FunctionEvaluationError {
68    InvalidArgument(usize),
69    InvalidArgumentCount,
70    IndexError(IndexError),
71    OverflowError,
72    OutofRange,
73    InvalidFormat { expected: String },
74    CorruptData,
75    InvalidType { expected: String },
76}
77
78impl PartialEq for FunctionEvaluationError {
79    fn eq(&self, other: &Self) -> bool {
80        match (self, other) {
81            (
82                FunctionEvaluationError::InvalidArgument(a),
83                FunctionEvaluationError::InvalidArgument(b),
84            ) => a == b,
85            (
86                FunctionEvaluationError::InvalidArgumentCount,
87                FunctionEvaluationError::InvalidArgumentCount,
88            ) => true,
89            (FunctionEvaluationError::IndexError(a), FunctionEvaluationError::IndexError(b)) => {
90                a == b
91            }
92            (FunctionEvaluationError::OverflowError, FunctionEvaluationError::OverflowError) => {
93                true
94            }
95            (FunctionEvaluationError::OutofRange, FunctionEvaluationError::OutofRange) => true,
96            (
97                FunctionEvaluationError::InvalidFormat { .. },
98                FunctionEvaluationError::InvalidFormat { .. },
99            ) => true,
100            (FunctionEvaluationError::CorruptData, FunctionEvaluationError::CorruptData) => true,
101            (
102                FunctionEvaluationError::InvalidType { .. },
103                FunctionEvaluationError::InvalidType { .. },
104            ) => true,
105            _ => false,
106        }
107    }
108}
109
110impl fmt::Display for FunctionEvaluationError {
111    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112        match self {
113            FunctionEvaluationError::InvalidArgument(arg) => write!(f, "Invalid argument: {}", arg),
114            FunctionEvaluationError::InvalidArgumentCount => write!(f, "Invalid argument count"),
115            FunctionEvaluationError::IndexError(err) => write!(f, "Index error: {}", err),
116            FunctionEvaluationError::OverflowError => write!(f, "Overflow error"),
117            FunctionEvaluationError::OutofRange => write!(f, "Out of range"),
118            FunctionEvaluationError::InvalidFormat { expected } => {
119                write!(f, "Invalid format, expected: {}", expected)
120            }
121            FunctionEvaluationError::CorruptData => write!(f, "Invalid accumulator"),
122            FunctionEvaluationError::InvalidType { expected } => {
123                write!(f, "Invalid type, expected: {}", expected)
124            }
125        }
126    }
127}
128
129impl fmt::Display for FunctionError {
130    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
131        write!(f, "Function: {}, Error: {}", self.function_name, self.error)
132    }
133}
134
135#[derive(Debug)]
136pub enum OutOfRangeType {
137    IndexOutOfRange,
138    TemporalDurationOutOfRange,
139    TemporalInstantOutOfRange,
140}
141
142impl From<IndexError> for FunctionEvaluationError {
143    fn from(e: IndexError) -> Self {
144        FunctionEvaluationError::IndexError(e)
145    }
146}
147
148impl From<IndexError> for EvaluationError {
149    fn from(e: IndexError) -> Self {
150        EvaluationError::IndexError(e)
151    }
152}
153
154impl From<MiddlewareError> for EvaluationError {
155    fn from(e: MiddlewareError) -> Self {
156        EvaluationError::MiddlewareError(e)
157    }
158}
159
160impl Display for EvaluationError {
161    // Match the variant and handle the display differently for each variant
162    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
163        format!("{:?}", self).fmt(f)
164    }
165}
166
167impl Error for EvaluationError {
168    fn source(&self) -> Option<&(dyn Error + 'static)> {
169        None
170    }
171}