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 best_by: Option<BestByClause>,
72 pub output: RuleOutput,
73}
74
75#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
77pub enum RuleCondition {
78 IsReference(IsReference),
80 Expression(Expr),
82}
83
84#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
86pub struct IsReference {
87 pub subjects: Vec<String>,
88 pub rule_name: QualifiedName,
89 pub target: Option<String>,
90 pub negated: bool,
91}
92
93#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
99pub struct AlongBinding {
100 pub name: String,
101 pub expr: LocyExpr,
102}
103
104#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
106pub enum LocyExpr {
107 PrevRef(String),
109 Cypher(Expr),
111 BinaryOp {
113 left: Box<LocyExpr>,
114 op: LocyBinaryOp,
115 right: Box<LocyExpr>,
116 },
117 UnaryOp(UnaryOp, Box<LocyExpr>),
119}
120
121#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
122pub enum LocyBinaryOp {
123 Add,
124 Sub,
125 Mul,
126 Div,
127 Mod,
128 Pow,
129 And,
130 Or,
131 Xor,
132 }
134
135#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
141pub struct FoldBinding {
142 pub name: String,
143 pub aggregate: Expr,
144}
145
146#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
152pub struct BestByClause {
153 pub items: Vec<BestByItem>,
154}
155
156#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
158pub struct BestByItem {
159 pub expr: Expr,
160 pub ascending: bool,
161}
162
163#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
169pub enum RuleOutput {
170 Yield(YieldClause),
171 Derive(DeriveClause),
172}
173
174#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
176pub struct YieldClause {
177 pub items: Vec<LocyYieldItem>,
178}
179
180#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
182pub struct LocyYieldItem {
183 pub is_key: bool,
184 pub expr: Expr,
185 pub alias: Option<String>,
186}
187
188#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
194pub enum DeriveClause {
195 Patterns(Vec<DerivePattern>),
196 Merge(String, String),
197}
198
199#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
200pub struct DerivePattern {
201 pub direction: Direction,
202 pub source: DeriveNodeSpec,
203 pub edge: DeriveEdgeSpec,
204 pub target: DeriveNodeSpec,
205}
206
207#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
208pub struct DeriveNodeSpec {
209 pub is_new: bool,
210 pub variable: String,
211 pub labels: Vec<String>,
212 pub properties: Option<Expr>,
213}
214
215#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
216pub struct DeriveEdgeSpec {
217 pub edge_type: String,
218 pub properties: Option<Expr>,
219}
220
221#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
227pub struct GoalQuery {
228 pub rule_name: QualifiedName,
229 pub where_expr: Expr,
230 pub return_clause: Option<ReturnClause>,
231}
232
233#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
239pub struct DeriveCommand {
240 pub rule_name: QualifiedName,
241 pub where_expr: Option<Expr>,
242}
243
244#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
250pub struct AssumeBlock {
251 pub mutations: Vec<crate::ast::Clause>,
252 pub body: Vec<LocyStatement>,
253}
254
255#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
261pub struct AbduceQuery {
262 pub negated: bool,
263 pub rule_name: QualifiedName,
264 pub where_expr: Expr,
265 pub return_clause: Option<ReturnClause>,
266}
267
268#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
274pub struct ExplainRule {
275 pub rule_name: QualifiedName,
276 pub where_expr: Expr,
277 pub return_clause: Option<ReturnClause>,
278}