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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use std::fmt::{Display, Formatter, Result};
use crate::query::Comparison;
#[derive(Clone, Debug)]
enum Operator {
And,
Or,
}
impl Display for Operator {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
write!(
f,
"{}",
match self {
Self::And => "&&",
Self::Or => "||",
}
)
}
}
/// Allows to filter a query according to different [`Comparison`].
#[derive(Clone, Debug)]
pub struct Filter {
comparisons: Vec<Comparison>,
operators: Vec<Operator>,
}
impl Filter {
/// Instantiates a new query filter from a comparison item
///
/// # Example
///
/// ```rust
/// # use aragog::query::{Comparison, Filter};
/// let filter = Filter::new(Comparison::field("age").greater_than(10));
/// ```
#[must_use]
#[inline]
pub fn new(comparison: Comparison) -> Self {
Self {
comparisons: vec![comparison],
operators: vec![],
}
}
/// Appends the filter current condition(s) with a new one with a `AND` logic.
///
/// # Example
///
/// ```rust
/// # use aragog::query::{Comparison, Filter};
/// let mut filter = Filter::new(Comparison::field("age").greater_than(10));
/// filter = filter.and(Comparison::field("username").in_str_array(&["felix", "felixm"]));
/// ```
///
#[must_use]
#[inline]
pub fn and(mut self, comparison: Comparison) -> Self {
self.comparisons.push(comparison);
self.operators.push(Operator::And);
self
}
/// Appends the filter current condition(s) with a new one with a `OR` logic.
///
/// # Example
///
/// ```rust
/// # use aragog::query::{Comparison, Filter};
/// let mut filter = Filter::new(Comparison::field("age").greater_than(10));
/// filter = filter.or(Comparison::field("username").in_str_array(&["felix", "felixm"]));
/// ```
///
#[must_use]
#[inline]
pub fn or(mut self, comparison: Comparison) -> Self {
self.comparisons.push(comparison);
self.operators.push(Operator::Or);
self
}
/// Renders the AQL string corresponding to the current `Filter`. The query will go out of scope.
///
/// # Example
///
/// ```rust
/// # use aragog::query::{Comparison, Filter};
/// let mut filter = Filter::new(Comparison::field("age").greater_than(10)).
/// or(Comparison::field("username").in_str_array(&["felix", "felixm"]));
/// assert_eq!(filter.to_aql("i"), String::from(r#"i.age > 10 || i.username IN ["felix", "felixm"]"#));
/// ```
#[must_use]
#[deprecated(since = "0.17.0", note = "use `aql_str` instead")]
pub fn to_aql(&self, collection_id: &str) -> String {
self.aql_str(collection_id)
}
/// Renders the AQL string corresponding to the current `Filter`. The query will go out of scope.
///
/// # Example
///
/// ```rust
/// # use aragog::query::{Comparison, Filter};
/// let mut filter = Filter::new(Comparison::field("age").greater_than(10)).
/// or(Comparison::field("username").in_str_array(&["felix", "felixm"]));
/// assert_eq!(filter.aql_str("i"), String::from(r#"i.age > 10 || i.username IN ["felix", "felixm"]"#));
/// ```
#[must_use]
pub fn aql_str(&self, collection_id: &str) -> String {
let mut res = String::new();
for (i, comparison) in self.comparisons.iter().enumerate() {
let operator_str = if i >= self.operators.len() {
String::new()
} else {
format!(" {}", self.operators[i])
};
res = format!(
"{} {}{}",
res,
comparison.aql_str(collection_id),
operator_str
);
}
String::from(res.trim_start())
}
}