1use serde::{Deserialize, Serialize};
2
3use crate::ast::{Direction, Expr, Pattern, Query, ReturnClause, UnaryOp};
4
5#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
7pub struct LocyProgram {
8 pub module: Option<ModuleDecl>,
9 pub uses: Vec<UseDecl>,
10 pub statements: Vec<LocyStatement>,
11}
12
13#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
15pub struct QualifiedName {
16 pub parts: Vec<String>,
17}
18
19impl std::fmt::Display for QualifiedName {
20 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21 write!(f, "{}", self.parts.join("."))
22 }
23}
24
25#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
27pub struct ModuleDecl {
28 pub name: QualifiedName,
29}
30
31#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
33pub struct UseDecl {
34 pub name: QualifiedName,
35 pub imports: Option<Vec<String>>,
37}
38
39#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
41pub enum LocyStatement {
42 Cypher(Query),
44 Rule(RuleDefinition),
46 GoalQuery(GoalQuery),
48 DeriveCommand(DeriveCommand),
50 AssumeBlock(AssumeBlock),
52 AbduceQuery(AbduceQuery),
54 ExplainRule(ExplainRule),
56}
57
58#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
64pub struct RuleDefinition {
65 pub name: QualifiedName,
66 pub priority: Option<i64>,
67 pub match_pattern: Pattern,
68 pub where_conditions: Vec<RuleCondition>,
69 pub along: Vec<AlongBinding>,
70 pub fold: Vec<FoldBinding>,
71 pub having: Vec<Expr>,
74 pub best_by: Option<BestByClause>,
75 pub output: RuleOutput,
76}
77
78#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
80pub enum RuleCondition {
81 IsReference(IsReference),
83 Expression(Expr),
85}
86
87#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
89pub struct IsReference {
90 pub subjects: Vec<String>,
91 pub rule_name: QualifiedName,
92 pub target: Option<String>,
93 pub negated: bool,
94}
95
96#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
102pub struct AlongBinding {
103 pub name: String,
104 pub expr: LocyExpr,
105}
106
107#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
109pub enum LocyExpr {
110 PrevRef(String),
112 Cypher(Expr),
114 BinaryOp {
116 left: Box<LocyExpr>,
117 op: LocyBinaryOp,
118 right: Box<LocyExpr>,
119 },
120 UnaryOp(UnaryOp, Box<LocyExpr>),
122}
123
124#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
125pub enum LocyBinaryOp {
126 Add,
127 Sub,
128 Mul,
129 Div,
130 Mod,
131 Pow,
132 And,
133 Or,
134 Xor,
135 }
137
138#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
144pub struct FoldBinding {
145 pub name: String,
146 pub aggregate: Expr,
147}
148
149#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
155pub struct BestByClause {
156 pub items: Vec<BestByItem>,
157}
158
159#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
161pub struct BestByItem {
162 pub expr: Expr,
163 pub ascending: bool,
164}
165
166#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
172pub enum RuleOutput {
173 Yield(YieldClause),
174 Derive(DeriveClause),
175}
176
177#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
179pub struct YieldClause {
180 pub items: Vec<LocyYieldItem>,
181}
182
183#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
185pub struct LocyYieldItem {
186 pub is_key: bool,
187 pub is_prob: bool,
188 pub expr: Expr,
189 pub alias: Option<String>,
190}
191
192#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
198pub enum DeriveClause {
199 Patterns(Vec<DerivePattern>),
200 Merge(String, String),
201}
202
203#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
204pub struct DerivePattern {
205 pub direction: Direction,
206 pub source: DeriveNodeSpec,
207 pub edge: DeriveEdgeSpec,
208 pub target: DeriveNodeSpec,
209}
210
211#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
212pub struct DeriveNodeSpec {
213 pub is_new: bool,
214 pub variable: String,
215 pub labels: Vec<String>,
216 pub properties: Option<Expr>,
217}
218
219#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
220pub struct DeriveEdgeSpec {
221 pub edge_type: String,
222 pub properties: Option<Expr>,
223}
224
225#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
231pub struct GoalQuery {
232 pub rule_name: QualifiedName,
233 pub where_expr: Option<Expr>,
234 pub return_clause: Option<ReturnClause>,
235}
236
237#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
243pub struct DeriveCommand {
244 pub rule_name: QualifiedName,
245 pub where_expr: Option<Expr>,
246}
247
248#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
254pub struct AssumeBlock {
255 pub mutations: Vec<crate::ast::Clause>,
256 pub body: Vec<LocyStatement>,
257}
258
259#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
265pub struct AbduceQuery {
266 pub negated: bool,
267 pub rule_name: QualifiedName,
268 pub where_expr: Option<Expr>,
269 pub return_clause: Option<ReturnClause>,
270}
271
272#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
278pub struct ExplainRule {
279 pub rule_name: QualifiedName,
280 pub where_expr: Option<Expr>,
281 pub return_clause: Option<ReturnClause>,
282}