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 is_prob: bool,
185 pub expr: Expr,
186 pub alias: Option<String>,
187}
188
189#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
195pub enum DeriveClause {
196 Patterns(Vec<DerivePattern>),
197 Merge(String, String),
198}
199
200#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
201pub struct DerivePattern {
202 pub direction: Direction,
203 pub source: DeriveNodeSpec,
204 pub edge: DeriveEdgeSpec,
205 pub target: DeriveNodeSpec,
206}
207
208#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
209pub struct DeriveNodeSpec {
210 pub is_new: bool,
211 pub variable: String,
212 pub labels: Vec<String>,
213 pub properties: Option<Expr>,
214}
215
216#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
217pub struct DeriveEdgeSpec {
218 pub edge_type: String,
219 pub properties: Option<Expr>,
220}
221
222#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
228pub struct GoalQuery {
229 pub rule_name: QualifiedName,
230 pub where_expr: Option<Expr>,
231 pub return_clause: Option<ReturnClause>,
232}
233
234#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
240pub struct DeriveCommand {
241 pub rule_name: QualifiedName,
242 pub where_expr: Option<Expr>,
243}
244
245#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
251pub struct AssumeBlock {
252 pub mutations: Vec<crate::ast::Clause>,
253 pub body: Vec<LocyStatement>,
254}
255
256#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
262pub struct AbduceQuery {
263 pub negated: bool,
264 pub rule_name: QualifiedName,
265 pub where_expr: Option<Expr>,
266 pub return_clause: Option<ReturnClause>,
267}
268
269#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
275pub struct ExplainRule {
276 pub rule_name: QualifiedName,
277 pub where_expr: Option<Expr>,
278 pub return_clause: Option<ReturnClause>,
279}