Skip to main content

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    FormatError { expected: String },
53}
54
55#[derive(Debug)]
56pub struct FunctionError {
57    pub function_name: String,
58    pub error: FunctionEvaluationError,
59}
60
61impl PartialEq for FunctionError {
62    fn eq(&self, other: &Self) -> bool {
63        self.error == other.error
64    }
65}
66
67#[derive(Debug)]
68pub enum FunctionEvaluationError {
69    InvalidArgument(usize),
70    InvalidArgumentCount,
71    IndexError(IndexError),
72    OverflowError,
73    OutofRange,
74    InvalidFormat { expected: String },
75    CorruptData,
76    InvalidType { expected: String },
77    EvaluationError(Box<EvaluationError>),
78}
79
80impl PartialEq for FunctionEvaluationError {
81    fn eq(&self, other: &Self) -> bool {
82        match (self, other) {
83            (
84                FunctionEvaluationError::InvalidArgument(a),
85                FunctionEvaluationError::InvalidArgument(b),
86            ) => a == b,
87            (
88                FunctionEvaluationError::InvalidArgumentCount,
89                FunctionEvaluationError::InvalidArgumentCount,
90            ) => true,
91            (FunctionEvaluationError::IndexError(a), FunctionEvaluationError::IndexError(b)) => {
92                a == b
93            }
94            (FunctionEvaluationError::OverflowError, FunctionEvaluationError::OverflowError) => {
95                true
96            }
97            (FunctionEvaluationError::OutofRange, FunctionEvaluationError::OutofRange) => true,
98            (
99                FunctionEvaluationError::InvalidFormat { .. },
100                FunctionEvaluationError::InvalidFormat { .. },
101            ) => true,
102            (FunctionEvaluationError::CorruptData, FunctionEvaluationError::CorruptData) => true,
103            (
104                FunctionEvaluationError::InvalidType { .. },
105                FunctionEvaluationError::InvalidType { .. },
106            ) => true,
107            _ => false,
108        }
109    }
110}
111
112impl fmt::Display for FunctionEvaluationError {
113    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
114        match self {
115            FunctionEvaluationError::InvalidArgument(arg) => write!(f, "Invalid argument: {arg}"),
116            FunctionEvaluationError::InvalidArgumentCount => write!(f, "Invalid argument count"),
117            FunctionEvaluationError::IndexError(err) => write!(f, "Index error: {err}"),
118            FunctionEvaluationError::OverflowError => write!(f, "Overflow error"),
119            FunctionEvaluationError::OutofRange => write!(f, "Out of range"),
120            FunctionEvaluationError::InvalidFormat { expected } => {
121                write!(f, "Invalid format, expected: {expected}")
122            }
123            FunctionEvaluationError::CorruptData => write!(f, "Invalid accumulator"),
124            FunctionEvaluationError::InvalidType { expected } => {
125                write!(f, "Invalid type, expected: {expected}")
126            }
127            FunctionEvaluationError::EvaluationError(err) => write!(f, "Evaluation error: {err}"),
128        }
129    }
130}
131
132impl fmt::Display for FunctionError {
133    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
134        write!(f, "Function: {}, Error: {}", self.function_name, self.error)
135    }
136}
137
138#[derive(Debug)]
139pub enum OutOfRangeType {
140    IndexOutOfRange,
141    TemporalDurationOutOfRange,
142    TemporalInstantOutOfRange,
143}
144
145impl From<IndexError> for FunctionEvaluationError {
146    fn from(e: IndexError) -> Self {
147        FunctionEvaluationError::IndexError(e)
148    }
149}
150
151impl From<IndexError> for EvaluationError {
152    fn from(e: IndexError) -> Self {
153        EvaluationError::IndexError(e)
154    }
155}
156
157impl From<MiddlewareError> for EvaluationError {
158    fn from(e: MiddlewareError) -> Self {
159        EvaluationError::MiddlewareError(e)
160    }
161}
162
163impl Display for EvaluationError {
164    // Match the variant and handle the display differently for each variant
165    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
166        format!("{self:?}").fmt(f)
167    }
168}
169
170impl Error for EvaluationError {
171    fn source(&self) -> Option<&(dyn Error + 'static)> {
172        None
173    }
174}