/* 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 */ pub mod binning; use crate::{ filter::binning::{Binning, BinningComponent}, query::Filter, }; impl Filter { pub fn get_bins(&self) -> Vec { fn recurse(f: &Filter) -> Vec> { match f { 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) } }