1use std::collections::HashMap;
4
5#[derive(Clone, Debug)]
9pub enum QueryValue {
10 Null,
11 Integer(i64),
12 Float(f64),
13 Text(String),
14 Blob(Vec<u8>),
15}
16
17#[derive(Debug, Clone)]
19pub struct GqlQuery {
20 pub pattern: MatchPattern,
21 pub where_clause: WhereExpr,
22 pub return_items: Vec<ReturnItem>,
23 pub limit: Option<usize>,
24}
25
26#[derive(Debug, Clone)]
28pub enum WhereExpr {
29 And(Box<WhereExpr>, Box<WhereExpr>),
31 Or(Box<WhereExpr>, Box<WhereExpr>),
33 Condition(Condition),
35 True,
37}
38
39impl WhereExpr {
40 pub fn conditions(&self) -> impl Iterator<Item = &Condition> {
42 let mut stack = vec![self];
43 let mut out: Vec<&Condition> = Vec::new();
44 while let Some(expr) = stack.pop() {
45 match expr {
46 WhereExpr::Condition(c) => out.push(c),
47 WhereExpr::And(l, r) | WhereExpr::Or(l, r) => {
48 stack.push(r);
49 stack.push(l);
50 }
51 WhereExpr::True => {}
52 }
53 }
54 out.into_iter()
55 }
56
57 pub fn for_each_condition_mut(&mut self, f: &mut impl FnMut(&mut Condition)) {
59 match self {
60 WhereExpr::Condition(c) => f(c),
61 WhereExpr::And(l, r) | WhereExpr::Or(l, r) => {
62 l.for_each_condition_mut(f);
63 r.for_each_condition_mut(f);
64 }
65 WhereExpr::True => {}
66 }
67 }
68
69 pub fn is_true(&self) -> bool {
71 matches!(self, WhereExpr::True)
72 }
73}
74
75#[derive(Debug, Clone, PartialEq, Eq)]
77pub enum ReturnItem {
78 Variable(String),
79 Property(String, String),
80}
81
82impl ReturnItem {
83 pub fn variable(&self) -> &str {
85 match self {
86 Self::Variable(v) | Self::Property(v, _) => v,
87 }
88 }
89}
90
91#[derive(Debug, Clone)]
93pub struct MatchPattern {
94 pub elements: Vec<PatternElement>,
95}
96
97impl MatchPattern {
98 pub fn nodes(&self) -> impl Iterator<Item = &NodePattern> {
100 self.elements.iter().filter_map(|e| match e {
101 PatternElement::Node(n) => Some(n),
102 _ => None,
103 })
104 }
105
106 pub fn edges(&self) -> impl Iterator<Item = &EdgePattern> {
108 self.elements.iter().filter_map(|e| match e {
109 PatternElement::Edge(e) => Some(e),
110 _ => None,
111 })
112 }
113
114 pub fn has_variable_length(&self) -> bool {
116 self.edges().any(|e| e.max_hops > 1)
117 }
118}
119
120#[derive(Debug, Clone)]
122pub enum PatternElement {
123 Node(NodePattern),
124 Edge(EdgePattern),
125}
126
127#[derive(Debug, Clone)]
129pub struct NodePattern {
130 pub variable: Option<String>,
131 pub kind: Option<String>,
132 pub entity_type: Option<String>,
134 pub properties: HashMap<String, ConditionValue>,
135}
136
137#[derive(Debug, Clone)]
139pub struct EdgePattern {
140 pub variable: Option<String>,
141 pub relations: Vec<String>,
142 pub direction: EdgeDirection,
143 pub min_hops: usize,
144 pub max_hops: usize,
145}
146
147#[derive(Debug, Clone, Copy, PartialEq, Eq)]
149pub enum EdgeDirection {
150 Out,
152 In,
154 Both,
156}
157
158#[derive(Debug, Clone)]
160pub struct Condition {
161 pub variable: String,
162 pub property: String,
163 pub op: CompareOp,
164 pub value: ConditionValue,
165}
166
167#[derive(Debug, Clone, Copy, PartialEq, Eq)]
169pub enum CompareOp {
170 Eq,
171 Neq,
172 Gt,
173 Lt,
174 Gte,
175 Lte,
176 Like,
177 Contains,
178 StartsWith,
179 In,
180 IsNotNull,
181}
182
183#[derive(Debug, Clone, PartialEq)]
187pub enum ConditionValue {
188 String(String),
189 Integer(i64),
191 Number(f64),
193 Bool(bool),
194 List(Vec<ConditionValue>),
196 Null,
198}