Skip to main content

fedimint_hbbft/binary_agreement/
bool_set.rs

1//! A single-byte representation of a set of boolean values.
2
3use rand_derive::Rand;
4use serde::{Deserialize, Serialize};
5
6/// The empty set of boolean values.
7pub const NONE: BoolSet = BoolSet(0b00);
8
9/// The set containing only `false`.
10pub const FALSE: BoolSet = BoolSet(0b01);
11
12/// The set containing only `true`.
13pub const TRUE: BoolSet = BoolSet(0b10);
14
15/// The set of both boolean values, `false` and `true`.
16pub const BOTH: BoolSet = BoolSet(0b11);
17
18/// A set of `bool` values, represented as a single byte in memory.
19#[derive(
20    Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Rand, Default,
21)]
22pub struct BoolSet(u8);
23
24impl BoolSet {
25    /// Inserts a boolean value into the `BoolSet` and returns `true` iff the `BoolSet` has
26    /// changed as a result.
27    pub fn insert(&mut self, b: bool) -> bool {
28        let prev = *self;
29        self.0 |= Self::from(b).0;
30        prev != *self
31    }
32
33    /// Removes a value from the set.
34    pub fn remove(&mut self, b: bool) {
35        self.0 &= Self::from(!b).0;
36    }
37
38    /// Returns `true` if the set contains the value `b`.
39    pub fn contains(self, b: bool) -> bool {
40        self.0 & Self::from(b).0 != 0
41    }
42
43    /// Returns `true` if every element of `self` is also an element of `other`.
44    pub fn is_subset(self, other: BoolSet) -> bool {
45        self.0 & other.0 == self.0
46    }
47
48    /// Returns `Some(b)` if the set is the singleton with the value `b`, otherwise `None`.
49    pub fn definite(self) -> Option<bool> {
50        match self {
51            FALSE => Some(false),
52            TRUE => Some(true),
53            _ => None,
54        }
55    }
56}
57
58impl From<bool> for BoolSet {
59    fn from(b: bool) -> Self {
60        if b {
61            TRUE
62        } else {
63            FALSE
64        }
65    }
66}
67
68/// An iterator over a `BoolSet`.
69#[derive(Clone, Copy, Debug)]
70pub struct BoolSetIter(BoolSet);
71
72impl Iterator for BoolSetIter {
73    type Item = bool;
74
75    fn next(&mut self) -> Option<bool> {
76        if self.0.contains(true) {
77            self.0.remove(true);
78            Some(true)
79        } else if self.0.contains(false) {
80            self.0.remove(false);
81            Some(false)
82        } else {
83            None
84        }
85    }
86}
87
88impl IntoIterator for BoolSet {
89    type Item = bool;
90    type IntoIter = BoolSetIter;
91
92    fn into_iter(self) -> Self::IntoIter {
93        BoolSetIter(self)
94    }
95}