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 offset: usize,
27 pub limit: Option<usize>,
28}
29
30#[derive(Debug, Clone)]
32pub enum WhereExpr {
33 And(Box<WhereExpr>, Box<WhereExpr>),
35 Or(Box<WhereExpr>, Box<WhereExpr>),
37 Condition(Condition),
39 True,
41}
42
43impl WhereExpr {
44 pub fn conditions(&self) -> impl Iterator<Item = &Condition> {
46 let mut stack = vec![self];
47 let mut out: Vec<&Condition> = Vec::new();
48 while let Some(expr) = stack.pop() {
49 match expr {
50 WhereExpr::Condition(c) => out.push(c),
51 WhereExpr::And(l, r) | WhereExpr::Or(l, r) => {
52 stack.push(r);
53 stack.push(l);
54 }
55 WhereExpr::True => {}
56 }
57 }
58 out.into_iter()
59 }
60
61 pub fn for_each_condition_mut(&mut self, f: &mut impl FnMut(&mut Condition)) {
63 match self {
64 WhereExpr::Condition(c) => f(c),
65 WhereExpr::And(l, r) | WhereExpr::Or(l, r) => {
66 l.for_each_condition_mut(f);
67 r.for_each_condition_mut(f);
68 }
69 WhereExpr::True => {}
70 }
71 }
72
73 pub fn is_true(&self) -> bool {
75 matches!(self, WhereExpr::True)
76 }
77}
78
79#[derive(Debug, Clone, PartialEq, Eq)]
81pub enum ReturnItem {
82 Variable(String),
83 Property(String, String),
84}
85
86impl ReturnItem {
87 pub fn variable(&self) -> &str {
89 match self {
90 Self::Variable(v) | Self::Property(v, _) => v,
91 }
92 }
93}
94
95#[derive(Debug, Clone)]
97pub struct MatchPattern {
98 pub elements: Vec<PatternElement>,
99}
100
101impl MatchPattern {
102 pub fn nodes(&self) -> impl Iterator<Item = &NodePattern> {
104 self.elements.iter().filter_map(|e| match e {
105 PatternElement::Node(n) => Some(n),
106 _ => None,
107 })
108 }
109
110 pub fn edges(&self) -> impl Iterator<Item = &EdgePattern> {
112 self.elements.iter().filter_map(|e| match e {
113 PatternElement::Edge(e) => Some(e),
114 _ => None,
115 })
116 }
117
118 pub fn has_variable_length(&self) -> bool {
120 self.edges().any(|e| e.max_hops > 1)
121 }
122}
123
124#[derive(Debug, Clone)]
126pub enum PatternElement {
127 Node(NodePattern),
128 Edge(EdgePattern),
129}
130
131#[derive(Debug, Clone)]
133pub struct NodePattern {
134 pub variable: Option<String>,
135 pub kind: Option<String>,
136 pub entity_type: Option<String>,
138 pub properties: HashMap<String, ConditionValue>,
139}
140
141#[derive(Debug, Clone)]
143pub struct EdgePattern {
144 pub variable: Option<String>,
145 pub relations: Vec<String>,
146 pub direction: EdgeDirection,
147 pub min_hops: usize,
148 pub max_hops: usize,
149}
150
151#[derive(Debug, Clone, Copy, PartialEq, Eq)]
153pub enum EdgeDirection {
154 Out,
156 In,
158 Both,
160}
161
162#[derive(Debug, Clone, PartialEq, Eq)]
164pub enum PropertyRef {
165 Field(String),
167 JsonPath(Vec<String>),
169}
170
171#[derive(Debug, Clone)]
174pub struct Condition {
175 pub variable: String,
176 pub property: PropertyRef,
177 pub op: CompareOp,
178 pub value: ConditionValue,
179}
180
181#[derive(Debug, Clone, Copy, PartialEq, Eq)]
183pub enum CompareOp {
184 Eq,
185 Neq,
186 Gt,
187 Lt,
188 Gte,
189 Lte,
190 Like,
191 Contains,
192 StartsWith,
193 In,
194 IsNotNull,
195 IsNull,
196}
197
198#[derive(Debug, Clone, PartialEq)]
202pub enum ConditionValue {
203 String(String),
204 Integer(i64),
206 Number(f64),
208 Bool(bool),
209 List(Vec<ConditionValue>),
211 Null,
213}