composable_indexes/aggregation/
boolean.rs

1use crate::{
2    Index, ShallowClone,
3    core::{Insert, Remove, Seal, Update},
4};
5
6/// An index that provide `any` & `all` queries for boolean inputs.
7#[derive(Clone)]
8pub struct Boolean {
9    true_count: usize,
10    false_count: usize,
11}
12
13impl ShallowClone for Boolean {}
14
15impl Default for Boolean {
16    fn default() -> Self {
17        Self::new()
18    }
19}
20
21impl Boolean {
22    pub fn new() -> Self {
23        Boolean {
24            true_count: 0,
25            false_count: 0,
26        }
27    }
28
29    /// Returns `true` if all indexed values are `true` (or if the collection is empty).
30    ///
31    /// An empty collection returns `true` (vacuous truth).
32    #[inline]
33    pub fn all(&self) -> bool {
34        self.false_count == 0
35    }
36
37    /// Returns `true` if at least one indexed value is `true`.
38    ///
39    /// An empty collection returns `false`.
40    #[inline]
41    pub fn any(&self) -> bool {
42        self.true_count > 0
43    }
44
45    /// Returns the count of `true` values.
46    #[inline]
47    pub fn true_count(&self) -> usize {
48        self.true_count
49    }
50
51    /// Returns the count of `false` values.
52    #[inline]
53    pub fn false_count(&self) -> usize {
54        self.false_count
55    }
56
57    /// Returns the total count of all values (both `true` and `false`).
58    #[inline]
59    pub fn total_count(&self) -> usize {
60        self.true_count + self.false_count
61    }
62}
63
64impl Index<bool> for Boolean {
65    #[inline]
66    fn insert(&mut self, _seal: Seal, op: &Insert<bool>) {
67        if *op.new {
68            self.true_count += 1;
69        } else {
70            self.false_count += 1;
71        }
72    }
73
74    #[inline]
75    fn remove(&mut self, _seal: Seal, op: &Remove<bool>) {
76        if *op.existing {
77            self.true_count -= 1;
78        } else {
79            self.false_count -= 1;
80        }
81    }
82
83    #[inline]
84    fn update(&mut self, _seal: Seal, op: &Update<bool>) {
85        match (op.existing, op.new) {
86            (false, true) => {
87                self.false_count -= 1;
88                self.true_count += 1;
89            }
90            (true, false) => {
91                self.true_count -= 1;
92                self.false_count += 1;
93            }
94            _ => {} // No change if both true or both false
95        }
96    }
97}