use rand_derive::Rand;
use serde::{Deserialize, Serialize};
pub const NONE: BoolSet = BoolSet(0b00);
pub const FALSE: BoolSet = BoolSet(0b01);
pub const TRUE: BoolSet = BoolSet(0b10);
pub const BOTH: BoolSet = BoolSet(0b11);
#[derive(
Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Rand, Default,
)]
pub struct BoolSet(u8);
impl BoolSet {
pub fn insert(&mut self, b: bool) -> bool {
let prev = *self;
self.0 |= Self::from(b).0;
prev != *self
}
pub fn remove(&mut self, b: bool) {
self.0 &= Self::from(!b).0;
}
pub fn contains(self, b: bool) -> bool {
self.0 & Self::from(b).0 != 0
}
pub fn is_subset(self, other: BoolSet) -> bool {
self.0 & other.0 == self.0
}
pub fn definite(self) -> Option<bool> {
match self {
FALSE => Some(false),
TRUE => Some(true),
_ => None,
}
}
}
impl From<bool> for BoolSet {
fn from(b: bool) -> Self {
if b {
TRUE
} else {
FALSE
}
}
}
#[derive(Clone, Copy, Debug)]
pub struct BoolSetIter(BoolSet);
impl Iterator for BoolSetIter {
type Item = bool;
fn next(&mut self) -> Option<bool> {
if self.0.contains(true) {
self.0.remove(true);
Some(true)
} else if self.0.contains(false) {
self.0.remove(false);
Some(false)
} else {
None
}
}
}
impl IntoIterator for BoolSet {
type Item = bool;
type IntoIter = BoolSetIter;
fn into_iter(self) -> Self::IntoIter {
BoolSetIter(self)
}
}