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
|
/*
This file is part of jellything (https://codeberg.org/metamuffin/jellything)
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
Copyright (C) 2026 metamuffin <metamuffin.org>
*/
pub mod binning;
use crate::{
filter::binning::{Binning, BinningComponent},
query::Filter,
};
impl Filter {
pub fn get_bins(&self) -> Vec<Binning> {
fn recurse(f: &Filter) -> Vec<Vec<BinningComponent>> {
match f {
Filter::True => vec![vec![]],
Filter::All(filters) => {
let mut o = vec![vec![]];
for filter in filters {
let mut new_o = Vec::new();
for par in recurse(filter) {
for mut prev in o.clone() {
prev.extend(par.clone());
new_o.push(prev);
}
}
o = new_o;
}
o
}
Filter::Any(filters) => filters.iter().flat_map(|f| recurse(f)).collect(),
Filter::Match(path, _) => vec![vec![BinningComponent::Match(path.to_owned())]],
Filter::Has(path) => vec![vec![BinningComponent::Has(path.to_owned())]],
}
}
recurse(self).into_iter().map(Binning::new).collect()
}
}
#[cfg(test)]
mod test {
use crate::{
filter::binning::{Binning, BinningComponent},
query::Filter,
};
use jellyobject::{Path, Tag};
#[test]
fn all() {
let f = Filter::All(vec![
Filter::Has(Path(vec![Tag(0)])),
Filter::Has(Path(vec![Tag(1)])),
]);
let bins = vec![Binning::new(vec![
BinningComponent::Has(Path(vec![Tag(0)])),
BinningComponent::Has(Path(vec![Tag(1)])),
])];
assert_eq!(f.get_bins(), bins)
}
#[test]
fn any() {
let f = Filter::Any(vec![
Filter::Has(Path(vec![Tag(0)])),
Filter::Has(Path(vec![Tag(1)])),
]);
let bins = vec![
Binning::new(vec![BinningComponent::Has(Path(vec![Tag(0)]))]),
Binning::new(vec![BinningComponent::Has(Path(vec![Tag(1)]))]),
];
assert_eq!(f.get_bins(), bins)
}
#[test]
fn nested() {
let f = Filter::All(vec![
Filter::Any(vec![
Filter::Has(Path(vec![Tag(0)])),
Filter::Has(Path(vec![Tag(1)])),
]),
Filter::Any(vec![
Filter::Has(Path(vec![Tag(2)])),
Filter::Has(Path(vec![Tag(3)])),
]),
]);
let bins = vec![
Binning::new(vec![
BinningComponent::Has(Path(vec![Tag(0)])),
BinningComponent::Has(Path(vec![Tag(2)])),
]),
Binning::new(vec![
BinningComponent::Has(Path(vec![Tag(1)])),
BinningComponent::Has(Path(vec![Tag(2)])),
]),
Binning::new(vec![
BinningComponent::Has(Path(vec![Tag(0)])),
BinningComponent::Has(Path(vec![Tag(3)])),
]),
Binning::new(vec![
BinningComponent::Has(Path(vec![Tag(1)])),
BinningComponent::Has(Path(vec![Tag(3)])),
]),
];
assert_eq!(f.get_bins(), bins)
}
}
|