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
use crate::model::note::Tag;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
#[serde(transparent)]
pub struct Query<T>(pub Vec<Vec<T>>);
impl<T> Query<T> {
/// Creates an empty [`Query`].
pub fn new() -> Self {
Query(vec![])
}
/// Creates [`Query`] from a vector which represents disjunction of conjunctions of `T`.
pub fn from_vec(vec: Vec<Vec<T>>) -> Self {
Query(vec)
}
/// Turns [`Query`] into a vector which represents disjunction of conjunctions of `T`.
pub fn into_vec(self) -> Vec<Vec<T>> {
self.0
}
/// Creates [`Query`] from a single element.
pub fn atom(x: impl Into<T>) -> Self {
Query(vec![vec![x.into()]])
}
/// Disjunction of two queries.
pub fn or(mut self, rhs: impl Into<Self>) -> Self {
let mut rhs = rhs.into();
self.0.extend(rhs.0.drain(..));
self
}
/// Conjunction of two queries. This operation is expensive for large rhs
/// and implemented just for syntactic brevity of small queries.
///
/// For building larger queries, consider using [`Query::or`] or [`Query::from_vec`].
pub fn and(mut self, rhs: impl Into<Self>) -> Self
where
T: Clone,
{
let rhs: Self = rhs.into();
let mut result = Vec::new();
for and_lhs in self.0.drain(..) {
for and_rhs in rhs.0.clone() {
let mut and = and_lhs.clone();
and.extend(and_rhs);
result.push(and);
}
}
Query(result)
}
}
impl<T> From<T> for Query<T> {
fn from(x: T) -> Query<T> {
Query(vec![vec![x]])
}
}
// we can't `impl<T, U> From<T> for Query<U> where T: Into<U>`
// however these `impl`s cover most use case
impl From<&str> for Query<String> {
fn from(x: &str) -> Query<String> {
Query(vec![vec![x.to_string()]])
}
}
impl From<&str> for Query<Tag> {
fn from(x: &str) -> Query<Tag> {
Query(vec![vec![Tag(x.to_string())]])
}
}