Skip to content

Commit e069b5c

Browse files
authored
Merge pull request #17 from j2inn/feature/STK-2059/add-visitor-to-filter
Add visitor to haystack filter processing
2 parents 97a674d + 0105677 commit e069b5c

File tree

11 files changed

+309
-140
lines changed

11 files changed

+309
-140
lines changed

Cargo.lock

Lines changed: 81 additions & 127 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "libhaystack"
3-
version = "1.0.12"
3+
version = "1.0.13"
44
description = "Rust implementation of the Haystack 4 data types, defs, filter, units, and encodings"
55
authors = ["J2 Innovations", "Radu Racariu <radur@j2inn.com>"]
66
edition = "2021"

src/haystack/defs/namespace.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ impl<'a> Namespace<'a> {
247247
Value::Symbol(sym) => self
248248
.subtypes
249249
.entry(sym.clone())
250-
.or_insert_with(Vec::new)
250+
.or_default()
251251
.push(def.clone()),
252252
_ => continue,
253253
}
@@ -542,16 +542,19 @@ impl<'a> Namespace<'a> {
542542
.map(|conjunct| conjunct.def_name())
543543
.map(|def_name| def_name.split('-').collect::<Vec<&str>>())
544544
.filter(|parts| !parts.is_empty())
545-
.fold(BTreeMap::default(), |mut map, parts| {
546-
let marker = parts[0];
547-
map.entry(marker.into()).or_insert_with(Vec::new).push(
548-
Vec::from(&parts[1..])
549-
.into_iter()
550-
.map(|v| v.into())
551-
.collect(),
552-
);
553-
map
554-
}),
545+
.fold(
546+
BTreeMap::default(),
547+
|mut map: BTreeMap<String, Vec<Vec<String>>>, parts| {
548+
let marker = parts[0];
549+
map.entry(marker.into()).or_default().push(
550+
Vec::from(&parts[1..])
551+
.into_iter()
552+
.map(|v| v.into())
553+
.collect(),
554+
);
555+
map
556+
},
557+
),
555558
)
556559
}
557560

src/haystack/filter/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,9 @@ impl Display for Filter {
7171
self.or.fmt(f)
7272
}
7373
}
74+
75+
impl Visitable for Filter {
76+
fn accept_visitor(&self, visitor: &mut impl Visitor) {
77+
self.or.accept_visitor(visitor);
78+
}
79+
}

src/haystack/filter/nodes.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,38 @@ use crate::val::Symbol;
1010
use std::collections::HashSet;
1111
use std::fmt::{Display, Formatter, Result};
1212

13+
/// A visitable that accepts a visitor.
14+
pub trait Visitable {
15+
fn accept_visitor(&self, visitor: &mut impl Visitor);
16+
}
17+
18+
/// A visitor trait used for working with a generated filter AST.
19+
pub trait Visitor {
20+
fn visit_cond_or(&mut self, node: &Or);
21+
22+
fn visit_cond_and(&mut self, node: &And);
23+
24+
fn visit_parens(&mut self, node: &Parens);
25+
26+
fn visit_has(&mut self, node: &Has);
27+
28+
fn visit_missing(&mut self, node: &Missing);
29+
30+
fn visit_is_a(&mut self, node: &IsA);
31+
32+
fn visit_wildcard_equals(&mut self, node: &WildcardEq);
33+
34+
fn visit_relation(&mut self, node: &Relation);
35+
36+
fn visit_cmp(&mut self, node: &Cmp);
37+
}
38+
1339
/// A Haystack Filter Or expression
1440
#[derive(PartialEq, PartialOrd, Clone, Debug)]
1541
pub struct Or {
1642
pub ands: Vec<And>,
1743
}
44+
1845
impl Display for Or {
1946
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
2047
self.ands
@@ -37,6 +64,12 @@ impl Eval for Or {
3764
}
3865
}
3966

67+
impl Visitable for Or {
68+
fn accept_visitor(&self, visitor: &mut impl Visitor) {
69+
visitor.visit_cond_or(self);
70+
}
71+
}
72+
4073
/// A Haystack Filter And expression
4174
#[derive(PartialEq, PartialOrd, Clone, Debug)]
4275
pub struct And {
@@ -65,6 +98,12 @@ impl Display for And {
6598
}
6699
}
67100

101+
impl Visitable for And {
102+
fn accept_visitor(&self, visitor: &mut impl Visitor) {
103+
visitor.visit_cond_and(self);
104+
}
105+
}
106+
68107
/// A Haystack Filter terminal
69108
#[derive(PartialEq, PartialOrd, Clone, Debug)]
70109
pub enum Term {
@@ -105,6 +144,20 @@ impl Display for Term {
105144
}
106145
}
107146

147+
impl Visitable for Term {
148+
fn accept_visitor(&self, visitor: &mut impl Visitor) {
149+
match self {
150+
Term::Parens(parens) => parens.accept_visitor(visitor),
151+
Term::Has(has) => has.accept_visitor(visitor),
152+
Term::Missing(missing) => missing.accept_visitor(visitor),
153+
Term::IsA(isa) => isa.accept_visitor(visitor),
154+
Term::WildcardEq(wildcard_eq) => wildcard_eq.accept_visitor(visitor),
155+
Term::Relation(rel) => rel.accept_visitor(visitor),
156+
Term::Cmp(cmp) => cmp.accept_visitor(visitor),
157+
}
158+
}
159+
}
160+
108161
/// Filter compare operators
109162
#[derive(PartialEq, Eq, PartialOrd, Clone, Debug)]
110163
pub enum CmpOp {
@@ -170,6 +223,12 @@ impl Display for Cmp {
170223
}
171224
}
172225

226+
impl Visitable for Cmp {
227+
fn accept_visitor(&self, visitor: &mut impl Visitor) {
228+
visitor.visit_cmp(self);
229+
}
230+
}
231+
173232
/// Missing term
174233
#[derive(PartialEq, Eq, PartialOrd, Clone, Debug)]
175234
pub struct Missing {
@@ -188,6 +247,12 @@ impl Display for Missing {
188247
}
189248
}
190249

250+
impl Visitable for Missing {
251+
fn accept_visitor(&self, visitor: &mut impl Visitor) {
252+
visitor.visit_missing(self);
253+
}
254+
}
255+
191256
/// Parenthesis term
192257
#[derive(PartialEq, PartialOrd, Clone, Debug)]
193258
pub struct Parens {
@@ -207,6 +272,12 @@ impl Display for Parens {
207272
}
208273
}
209274

275+
impl Visitable for Parens {
276+
fn accept_visitor(&self, visitor: &mut impl Visitor) {
277+
visitor.visit_parens(self);
278+
}
279+
}
280+
210281
/// Has term
211282
#[derive(PartialEq, Eq, PartialOrd, Clone, Debug)]
212283
pub struct Has {
@@ -224,6 +295,12 @@ impl Display for Has {
224295
}
225296
}
226297

298+
impl Visitable for Has {
299+
fn accept_visitor(&self, visitor: &mut impl Visitor) {
300+
visitor.visit_has(self);
301+
}
302+
}
303+
227304
/// Is A term
228305
#[derive(PartialEq, Eq, PartialOrd, Clone, Debug)]
229306
pub struct IsA {
@@ -242,6 +319,12 @@ impl Display for IsA {
242319
}
243320
}
244321

322+
impl Visitable for IsA {
323+
fn accept_visitor(&self, visitor: &mut impl Visitor) {
324+
visitor.visit_is_a(self);
325+
}
326+
}
327+
245328
/// Wildcard equality
246329
#[derive(PartialEq, Eq, PartialOrd, Clone, Debug)]
247330
pub struct WildcardEq {
@@ -290,6 +373,12 @@ impl Display for WildcardEq {
290373
}
291374
}
292375

376+
impl Visitable for WildcardEq {
377+
fn accept_visitor(&self, visitor: &mut impl Visitor) {
378+
visitor.visit_wildcard_equals(self);
379+
}
380+
}
381+
293382
/// Relation
294383
#[derive(PartialEq, Eq, PartialOrd, Clone, Debug)]
295384
pub struct Relation {
@@ -326,3 +415,9 @@ impl Display for Relation {
326415
}
327416
}
328417
}
418+
419+
impl Visitable for Relation {
420+
fn accept_visitor(&self, visitor: &mut impl Visitor) {
421+
visitor.visit_relation(self);
422+
}
423+
}

src/haystack/val/coord.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::{
1010
};
1111

1212
/// Coordinate latitude and longitude
13-
////
13+
///
1414
/// # Example
1515
/// Create a coord value
1616
/// ```
@@ -69,6 +69,7 @@ impl PartialEq for Coord {
6969

7070
impl Eq for Coord {}
7171

72+
#[allow(clippy::non_canonical_partial_ord_impl)]
7273
impl PartialOrd for Coord {
7374
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
7475
self.lat.partial_cmp(&other.lat).and_then(|ord| {

src/haystack/val/dict.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ impl DerefMut for Dict {
152152
}
153153
}
154154

155+
#[allow(clippy::non_canonical_partial_ord_impl)]
155156
impl PartialOrd for Dict {
156157
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
157158
self.value.partial_cmp(&other.value)

src/haystack/val/number.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ impl PartialEq for Number {
132132

133133
impl Eq for Number {}
134134

135+
#[allow(clippy::non_canonical_partial_ord_impl)]
135136
impl PartialOrd for Number {
136137
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
137138
if self.unit == other.unit {

src/haystack/val/reference.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ impl PartialEq for Ref {
5555
}
5656

5757
/// Implement partial ordering used in sorting for Ref
58+
#[allow(clippy::non_canonical_partial_ord_impl)]
5859
impl PartialOrd for Ref {
5960
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
6061
self.value.partial_cmp(&other.value)

tests/filter/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22

33
mod test_filter_defs;
44
mod test_haystack_filter;
5+
mod test_haystack_filter_visitor;

0 commit comments

Comments
 (0)