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