use selene_core::DbString;
use crate::{BinaryOp, GqlType, analyze::binding::BindingDeclKind};
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum TypeMismatchContext {
BinaryArithmetic {
op: BinaryOp,
side: Side,
},
BinaryComparison {
op: BinaryOp,
side: Side,
},
BinaryBoolean {
op: BinaryOp,
side: Side,
},
BinaryConcat {
side: Side,
},
BinaryStringPredicate {
op: BinaryOp,
side: Side,
},
UnaryNegate,
UnaryNot,
IsTruthValue,
IsTypedTarget,
IsNormalized,
NormalizeFunction,
TrimSource,
TrimCharacter,
PathConstructorElement {
position: usize,
},
CaseBranchUnification,
ListLiteralUnification,
InListUnification,
Condition {
clause: ConditionClause,
},
ProcedureArgument {
procedure: Box<[DbString]>,
parameter: DbString,
position: usize,
},
LimitAmount,
}
impl std::fmt::Display for TypeMismatchContext {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::BinaryArithmetic { op, side } => {
write!(f, "{side} operand of arithmetic operator {op:?}")
}
Self::BinaryComparison { op, side } => {
write!(f, "{side} operand of comparison operator {op:?}")
}
Self::BinaryBoolean { op, side } => {
write!(f, "{side} operand of boolean operator {op:?}")
}
Self::BinaryConcat { side } => write!(f, "{side} operand of concat operator"),
Self::BinaryStringPredicate { op, side } => {
write!(f, "{side} operand of string predicate {op:?}")
}
Self::UnaryNegate => f.write_str("operand of unary negate"),
Self::UnaryNot => f.write_str("operand of unary NOT"),
Self::IsTruthValue => f.write_str("IS <truth value> operand"),
Self::IsTypedTarget => f.write_str("IS TYPED target"),
Self::IsNormalized => f.write_str("IS NORMALIZED operand"),
Self::NormalizeFunction => f.write_str("NORMALIZE operand"),
Self::TrimSource => f.write_str("TRIM source operand"),
Self::TrimCharacter => f.write_str("TRIM character operand"),
Self::PathConstructorElement { position } => {
write!(f, "PATH element {position}")
}
Self::CaseBranchUnification => f.write_str("CASE branch result"),
Self::ListLiteralUnification => f.write_str("list literal element"),
Self::InListUnification => f.write_str("IN-list value"),
Self::Condition { clause } => write!(f, "{clause} condition"),
Self::ProcedureArgument {
procedure,
parameter,
position,
} => {
write!(f, "argument {position} ({parameter}) of ")?;
super::fmt_qualified_name(f, procedure)
}
Self::LimitAmount => f.write_str("LIMIT/OFFSET parameter"),
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ExpectedType {
Numeric,
Boolean,
String,
StringOrBytes,
Comparable,
ListStringBytesOrPath,
List,
LimitAmount,
Specific(GqlType),
}
impl std::fmt::Display for ExpectedType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Numeric => f.write_str("numeric"),
Self::Boolean => f.write_str("boolean"),
Self::String => f.write_str("string"),
Self::StringOrBytes => f.write_str("string or bytes"),
Self::Comparable => f.write_str("comparable"),
Self::ListStringBytesOrPath => f.write_str("list, string, bytes, or path"),
Self::List => f.write_str("list"),
Self::LimitAmount => f.write_str("non-negative integer"),
Self::Specific(ty) => write!(f, "{ty:?}"),
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Side {
Lhs,
Rhs,
}
impl std::fmt::Display for Side {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
Self::Lhs => "left",
Self::Rhs => "right",
})
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ConditionClause {
MatchWhere,
InlineWhere,
Filter,
Having,
WithWhere,
CaseWhen,
}
impl std::fmt::Display for ConditionClause {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
Self::MatchWhere => "MATCH WHERE",
Self::InlineWhere => "inline WHERE",
Self::Filter => "FILTER",
Self::Having => "HAVING",
Self::WithWhere => "WITH WHERE",
Self::CaseWhen => "CASE WHEN",
})
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PatternElementKind {
Node,
Edge,
Path,
}
impl PatternElementKind {
#[must_use]
pub const fn from_decl_kind(kind: BindingDeclKind) -> Option<Self> {
match kind {
BindingDeclKind::NodePattern | BindingDeclKind::InsertNode => Some(Self::Node),
BindingDeclKind::EdgePattern | BindingDeclKind::InsertEdge => Some(Self::Edge),
BindingDeclKind::PathBinding => Some(Self::Path),
BindingDeclKind::LetAlias
| BindingDeclKind::ForAlias
| BindingDeclKind::ProjectionAlias
| BindingDeclKind::YieldColumn => None,
}
}
}
impl std::fmt::Display for PatternElementKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(match self {
Self::Node => "node variable",
Self::Edge => "edge variable",
Self::Path => "path variable",
})
}
}