selene_gql/analyze/error/
context.rs1use selene_core::DbString;
4
5use crate::{BinaryOp, GqlType, analyze::binding::BindingDeclKind};
6
7#[derive(Clone, Debug, Eq, PartialEq)]
9pub enum TypeMismatchContext {
10 BinaryArithmetic {
12 op: BinaryOp,
14 side: Side,
16 },
17 BinaryComparison {
19 op: BinaryOp,
21 side: Side,
23 },
24 BinaryBoolean {
26 op: BinaryOp,
28 side: Side,
30 },
31 BinaryConcat {
33 side: Side,
35 },
36 BinaryStringPredicate {
38 op: BinaryOp,
40 side: Side,
42 },
43 UnaryNegate,
45 UnaryNot,
47 IsTruthValue,
49 IsTypedTarget,
51 IsNormalized,
53 NormalizeFunction,
55 TrimSource,
57 TrimCharacter,
59 PathConstructorElement {
61 position: usize,
63 },
64 CaseBranchUnification,
66 ListLiteralUnification,
68 InListUnification,
70 Condition {
72 clause: ConditionClause,
74 },
75 ProcedureArgument {
77 procedure: Box<[DbString]>,
79 parameter: DbString,
81 position: usize,
83 },
84 LimitAmount,
86}
87
88impl std::fmt::Display for TypeMismatchContext {
89 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90 match self {
91 Self::BinaryArithmetic { op, side } => {
92 write!(f, "{side} operand of arithmetic operator {op:?}")
93 }
94 Self::BinaryComparison { op, side } => {
95 write!(f, "{side} operand of comparison operator {op:?}")
96 }
97 Self::BinaryBoolean { op, side } => {
98 write!(f, "{side} operand of boolean operator {op:?}")
99 }
100 Self::BinaryConcat { side } => write!(f, "{side} operand of concat operator"),
101 Self::BinaryStringPredicate { op, side } => {
102 write!(f, "{side} operand of string predicate {op:?}")
103 }
104 Self::UnaryNegate => f.write_str("operand of unary negate"),
105 Self::UnaryNot => f.write_str("operand of unary NOT"),
106 Self::IsTruthValue => f.write_str("IS <truth value> operand"),
107 Self::IsTypedTarget => f.write_str("IS TYPED target"),
108 Self::IsNormalized => f.write_str("IS NORMALIZED operand"),
109 Self::NormalizeFunction => f.write_str("NORMALIZE operand"),
110 Self::TrimSource => f.write_str("TRIM source operand"),
111 Self::TrimCharacter => f.write_str("TRIM character operand"),
112 Self::PathConstructorElement { position } => {
113 write!(f, "PATH element {position}")
114 }
115 Self::CaseBranchUnification => f.write_str("CASE branch result"),
116 Self::ListLiteralUnification => f.write_str("list literal element"),
117 Self::InListUnification => f.write_str("IN-list value"),
118 Self::Condition { clause } => write!(f, "{clause} condition"),
119 Self::ProcedureArgument {
120 procedure,
121 parameter,
122 position,
123 } => {
124 write!(f, "argument {position} ({parameter}) of ")?;
125 super::fmt_qualified_name(f, procedure)
126 }
127 Self::LimitAmount => f.write_str("LIMIT/OFFSET parameter"),
128 }
129 }
130}
131
132#[derive(Clone, Debug, Eq, PartialEq)]
134pub enum ExpectedType {
135 Numeric,
137 Boolean,
139 String,
141 StringOrBytes,
143 Comparable,
145 ListStringBytesOrPath,
147 List,
149 LimitAmount,
151 Specific(GqlType),
153}
154
155impl std::fmt::Display for ExpectedType {
156 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
157 match self {
158 Self::Numeric => f.write_str("numeric"),
159 Self::Boolean => f.write_str("boolean"),
160 Self::String => f.write_str("string"),
161 Self::StringOrBytes => f.write_str("string or bytes"),
162 Self::Comparable => f.write_str("comparable"),
163 Self::ListStringBytesOrPath => f.write_str("list, string, bytes, or path"),
164 Self::List => f.write_str("list"),
165 Self::LimitAmount => f.write_str("non-negative integer"),
166 Self::Specific(ty) => write!(f, "{ty:?}"),
167 }
168 }
169}
170
171#[derive(Clone, Copy, Debug, Eq, PartialEq)]
173pub enum Side {
174 Lhs,
176 Rhs,
178}
179
180impl std::fmt::Display for Side {
181 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
182 f.write_str(match self {
183 Self::Lhs => "left",
184 Self::Rhs => "right",
185 })
186 }
187}
188
189#[derive(Clone, Copy, Debug, Eq, PartialEq)]
191pub enum ConditionClause {
192 MatchWhere,
194 InlineWhere,
196 Filter,
198 Having,
200 WithWhere,
202 CaseWhen,
204}
205
206impl std::fmt::Display for ConditionClause {
207 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
208 f.write_str(match self {
209 Self::MatchWhere => "MATCH WHERE",
210 Self::InlineWhere => "inline WHERE",
211 Self::Filter => "FILTER",
212 Self::Having => "HAVING",
213 Self::WithWhere => "WITH WHERE",
214 Self::CaseWhen => "CASE WHEN",
215 })
216 }
217}
218
219#[derive(Clone, Copy, Debug, Eq, PartialEq)]
226pub enum PatternElementKind {
227 Node,
229 Edge,
231 Path,
233}
234
235impl PatternElementKind {
236 #[must_use]
238 pub const fn from_decl_kind(kind: BindingDeclKind) -> Option<Self> {
239 match kind {
240 BindingDeclKind::NodePattern | BindingDeclKind::InsertNode => Some(Self::Node),
241 BindingDeclKind::EdgePattern | BindingDeclKind::InsertEdge => Some(Self::Edge),
242 BindingDeclKind::PathBinding => Some(Self::Path),
243 BindingDeclKind::LetAlias
244 | BindingDeclKind::ForAlias
245 | BindingDeclKind::ProjectionAlias
246 | BindingDeclKind::YieldColumn => None,
247 }
248 }
249}
250
251impl std::fmt::Display for PatternElementKind {
252 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
253 f.write_str(match self {
254 Self::Node => "node variable",
255 Self::Edge => "edge variable",
256 Self::Path => "path variable",
257 })
258 }
259}