1use crate::graph::bind_name::BindNameExt;
2use crate::ValueExpr;
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5use std::fmt::Debug;
6
7pub mod bind_name;
8
9#[allow(clippy::upper_case_acronyms)]
11#[derive(Debug, Clone, Eq, PartialEq)]
12#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
13pub enum DirectionFilter {
14 L, U, R, LU, UR, LR, LUR, }
22
23#[derive(Debug, Copy, Clone, Eq, PartialEq)]
25#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
26pub enum PathMode {
27 Walk,
29 Trail,
31 Acyclic,
33 Simple,
35}
36
37#[derive(Debug, Clone, Eq, PartialEq)]
39#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
40pub struct BindSpec(pub String);
41
42impl BindSpec {
43 pub fn is_anon(&self) -> bool {
46 self.0.is_anon()
47 }
48}
49
50#[derive(Default, Debug, Clone, Eq, PartialEq)]
52#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
53pub enum LabelFilter {
54 #[default]
55 Always,
56 Named(String),
57 Negated(Box<LabelFilter>),
58 Conjunction(Vec<LabelFilter>),
59 Disjunction(Vec<LabelFilter>),
60 Never,
61}
62
63#[derive(Default, Debug, Clone, Eq, PartialEq)]
65#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
66pub enum ValueFilter {
67 #[default]
68 Always,
69 Filter(Vec<ValueExpr>),
70}
71
72impl ValueFilter {
73 pub fn and(mut self, other: ValueFilter) -> ValueFilter {
74 self.extend(other);
75 self
76 }
77
78 pub fn extend(&mut self, other: ValueFilter) {
79 match other {
80 ValueFilter::Always => {}
81 ValueFilter::Filter(rhs) => match self {
82 ValueFilter::Always => {
83 *self = ValueFilter::Filter(rhs);
84 }
85 ValueFilter::Filter(lhs) => {
86 lhs.extend(rhs);
87 }
88 },
89 }
90 }
91}
92
93#[derive(Debug, Clone, Eq, PartialEq)]
95#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
96pub struct NodeFilter {
97 pub label: LabelFilter,
98 pub filter: ValueFilter,
99}
100
101#[derive(Debug, Clone, Eq, PartialEq)]
103#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
104pub struct EdgeFilter {
105 pub label: LabelFilter,
106 pub filter: ValueFilter,
107}
108
109#[derive(Debug, Clone, Eq, PartialEq)]
111#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
112pub struct TripleFilter {
113 pub lhs: NodeFilter,
114 pub e: EdgeFilter,
115 pub rhs: NodeFilter,
116}
117
118#[derive(Debug, Clone, Eq, PartialEq)]
120#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
121pub struct StepFilter {
122 pub dir: DirectionFilter,
123 pub triple: TripleFilter,
124}
125
126#[derive(Debug, Clone, Eq, PartialEq)]
128#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
129pub struct PathPattern {
130 pub head: NodeMatch,
131 pub tail: Vec<(DirectionFilter, EdgeMatch, NodeMatch)>,
132 pub filter: ValueFilter,
133 pub mode: PathMode,
134}
135
136#[derive(Debug, Clone, Eq, PartialEq)]
138#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
139pub struct NodeMatch {
140 pub binder: BindSpec,
141 pub spec: NodeFilter,
142}
143
144#[derive(Debug, Clone, Eq, PartialEq)]
146#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
147pub struct EdgeMatch {
148 pub binder: BindSpec,
149 pub spec: EdgeFilter,
150}
151
152#[derive(Debug, Clone, Eq, PartialEq)]
154#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
155pub struct TripleMatch {
156 pub binders: (BindSpec, BindSpec, BindSpec),
157 pub spec: StepFilter,
158 pub filter: ValueFilter,
159 pub path_mode: PathMode,
160}
161
162#[derive(Debug, Clone, Eq, PartialEq)]
164#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
165pub struct TripleSeriesMatch {
166 pub triples: Vec<TripleMatch>,
167 pub filter: ValueFilter,
168 pub path_mode: PathMode,
169}
170
171#[derive(Debug, Clone, Eq, PartialEq)]
173#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
174pub enum PathPatternMatch {
175 Node(NodeMatch),
176 Match(TripleMatch),
177 Concat(Vec<TripleSeriesMatch>, PathMode),
178}