diff options
Diffstat (limited to 'database/src/filter/binning.rs')
| -rw-r--r-- | database/src/filter/binning.rs | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/database/src/filter/binning.rs b/database/src/filter/binning.rs new file mode 100644 index 0000000..977d5d7 --- /dev/null +++ b/database/src/filter/binning.rs @@ -0,0 +1,52 @@ +/* + 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> +*/ + +use jellycommon::jellyobject::{Object, path::Path}; + +/// Sorted list of components to bin objects by filterable values. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Binning(Vec<BinningComponent>); + +#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)] +pub enum BinningComponent { + Has(Path), + Match(Path), +} + +impl Binning { + pub fn new(mut comps: Vec<BinningComponent>) -> Self { + comps.sort(); + Self(comps) + } + pub fn apply(&self, ob: Object<'_>, keys: &mut Vec<Vec<u8>>) { + for f in &self.0 { + f.apply(ob, keys); + } + } +} +impl BinningComponent { + pub fn apply(&self, ob: Object<'_>, keys: &mut Vec<Vec<u8>>) { + match self { + BinningComponent::Has(path) => { + let has = path.get_matching_value(ob).is_some(); + for co in keys { + co.push(has as u8) + } + } + BinningComponent::Match(path) => { + let mut new_out = Vec::new(); + for value in path.get_matching_values(ob) { + for mut co in keys.clone() { + co.extend((co.len() as u32).to_be_bytes()); + co.extend(value); + new_out.push(co); + } + } + *keys = new_out; + } + } + } +} |