drasi_core/path_solver/
match_path.rs1use drasi_query_ast::ast::Expression;
16
17use super::merge_relation_match;
18
19use super::merge_node_match;
20
21use crate::evaluation::EvaluationError;
22use std::collections::HashMap;
23use std::sync::Arc;
24
25use drasi_query_ast::ast;
26
27#[derive(Debug)]
28pub struct MatchPath {
29 pub slots: Vec<MatchPathSlot>,
30}
31
32impl MatchPath {
33 pub fn from_query(query_part: &ast::QueryPart) -> Result<Self, EvaluationError> {
34 let mut slots = Vec::new();
35
36 let mut alias_map = HashMap::new();
37
38 for mc in &query_part.match_clauses {
39 let slot_num = merge_node_match(&mc.start, &mut slots, &mut alias_map)?;
40 let mut prev_slot_num = slot_num;
41
42 for p in &mc.path {
43 let rel_slot_num = merge_relation_match(&p.0, &mut slots, &mut alias_map)?;
44 let node_slot_num = merge_node_match(&p.1, &mut slots, &mut alias_map)?;
45
46 match p.0.direction {
47 ast::Direction::Right => {
48 slots[prev_slot_num].out_slots.push(rel_slot_num);
49 slots[rel_slot_num].in_slots.push(prev_slot_num);
50
51 slots[rel_slot_num].out_slots.push(node_slot_num);
52 slots[node_slot_num].in_slots.push(rel_slot_num);
53 }
54 ast::Direction::Left => {
55 slots[prev_slot_num].in_slots.push(rel_slot_num);
56 slots[rel_slot_num].out_slots.push(prev_slot_num);
57
58 slots[rel_slot_num].in_slots.push(node_slot_num);
59 slots[node_slot_num].out_slots.push(rel_slot_num);
60 }
61 ast::Direction::Either => {
62 slots[prev_slot_num].in_slots.push(rel_slot_num);
63 slots[prev_slot_num].out_slots.push(rel_slot_num);
64 slots[rel_slot_num].in_slots.push(prev_slot_num);
65 slots[rel_slot_num].out_slots.push(prev_slot_num);
66
67 slots[node_slot_num].in_slots.push(rel_slot_num);
68 slots[node_slot_num].out_slots.push(rel_slot_num);
69 slots[rel_slot_num].in_slots.push(node_slot_num);
70 slots[rel_slot_num].out_slots.push(node_slot_num);
71 }
72 }
73
74 prev_slot_num = node_slot_num;
75 }
76 }
77
78 Ok(MatchPath { slots })
79 }
80}
81
82#[derive(Debug)]
83pub struct MatchPathSlot {
84 pub spec: SlotElementSpec,
85 pub in_slots: Vec<usize>,
86 pub out_slots: Vec<usize>,
87}
88
89#[derive(Debug)]
90pub struct SlotElementSpec {
91 pub annotation: Option<Arc<str>>,
92 pub labels: Vec<Arc<str>>,
93 pub predicates: Vec<Expression>,
94}
95
96impl SlotElementSpec {
97 pub fn new(
98 annotation: Option<Arc<str>>,
99 labels: Vec<Arc<str>>,
100 predicates: Vec<Expression>,
101 ) -> SlotElementSpec {
102 SlotElementSpec {
103 annotation,
104 labels,
105 predicates,
106 }
107 }
108
109 pub fn from_node_match(node_match: &ast::NodeMatch) -> SlotElementSpec {
110 let annotation = &node_match.annotation.name;
111 let labels = node_match.labels.clone();
112 let predicates = node_match.property_predicates.clone();
113
114 SlotElementSpec::new(annotation.clone(), labels, predicates)
115 }
116
117 pub fn from_relation_match(node_match: &ast::RelationMatch) -> SlotElementSpec {
118 let annotation = &node_match.annotation.name;
119 let labels = node_match.labels.clone();
120 let predicates = node_match.property_predicates.clone();
121
122 SlotElementSpec::new(annotation.clone(), labels, predicates)
123 }
124}