-
-
Notifications
You must be signed in to change notification settings - Fork 609
/
logical_ast.rs
93 lines (85 loc) · 2.63 KB
/
logical_ast.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use std::fmt;
use std::ops::Bound;
use crate::query::Occur;
use crate::schema::{Field, Term, Type};
use crate::Score;
#[derive(Clone)]
pub enum LogicalLiteral {
Term(Term),
Phrase(Vec<(usize, Term)>, u32),
Range {
field: Field,
value_type: Type,
lower: Bound<Term>,
upper: Bound<Term>,
},
All,
}
pub enum LogicalAst {
Clause(Vec<(Occur, LogicalAst)>),
Leaf(Box<LogicalLiteral>),
Boost(Box<LogicalAst>, Score),
}
impl LogicalAst {
pub fn boost(self, boost: Score) -> LogicalAst {
if (boost - 1.0).abs() < Score::EPSILON {
self
} else {
LogicalAst::Boost(Box::new(self), boost)
}
}
}
fn occur_letter(occur: Occur) -> &'static str {
match occur {
Occur::Must => "+",
Occur::MustNot => "-",
Occur::Should => "",
}
}
impl fmt::Debug for LogicalAst {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match *self {
LogicalAst::Clause(ref clause) => {
if clause.is_empty() {
write!(formatter, "<emptyclause>")?;
} else {
let (ref occur, ref subquery) = clause[0];
write!(formatter, "({}{:?}", occur_letter(*occur), subquery)?;
for &(ref occur, ref subquery) in &clause[1..] {
write!(formatter, " {}{:?}", occur_letter(*occur), subquery)?;
}
formatter.write_str(")")?;
}
Ok(())
}
LogicalAst::Boost(ref ast, boost) => write!(formatter, "{:?}^{}", ast, boost),
LogicalAst::Leaf(ref literal) => write!(formatter, "{:?}", literal),
}
}
}
impl From<LogicalLiteral> for LogicalAst {
fn from(literal: LogicalLiteral) -> LogicalAst {
LogicalAst::Leaf(Box::new(literal))
}
}
impl fmt::Debug for LogicalLiteral {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match *self {
LogicalLiteral::Term(ref term) => write!(formatter, "{:?}", term),
LogicalLiteral::Phrase(ref terms, slop) => {
write!(formatter, "\"{:?}\"", terms)?;
if slop > 0 {
write!(formatter, "~{:?}", slop)
} else {
Ok(())
}
}
LogicalLiteral::Range {
ref lower,
ref upper,
..
} => write!(formatter, "({:?} TO {:?})", lower, upper),
LogicalLiteral::All => write!(formatter, "*"),
}
}
}