From d5da84d967e1886526f89b0f24cb1be2cff73d0b Mon Sep 17 00:00:00 2001 From: Paul Hauner Date: Mon, 28 Jan 2019 11:23:01 +1100 Subject: [PATCH] Add `BitAnd` impl for BooleanBitfield --- eth2/utils/boolean-bitfield/src/lib.rs | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/eth2/utils/boolean-bitfield/src/lib.rs b/eth2/utils/boolean-bitfield/src/lib.rs index a00a081bec..16992c3fa0 100644 --- a/eth2/utils/boolean-bitfield/src/lib.rs +++ b/eth2/utils/boolean-bitfield/src/lib.rs @@ -114,6 +114,28 @@ impl cmp::PartialEq for BooleanBitfield { } } +/// Create a new bitfield that is a union of two other bitfields. +/// +/// For example `union(0101, 1000) == 1101` +impl std::ops::BitAnd for BooleanBitfield { + type Output = Self; + + fn bitand(self, other: Self) -> Self { + let (biggest, smallest) = if self.len() > other.len() { + (&self, &other) + } else { + (&other, &self) + }; + let mut new = biggest.clone(); + for i in 0..smallest.len() { + if let Ok(true) = smallest.get(i) { + new.set(i, true); + } + } + new + } +} + impl ssz::Encodable for BooleanBitfield { // ssz_append encodes Self according to the `ssz` spec. fn ssz_append(&self, s: &mut ssz::SszStream) { @@ -375,4 +397,12 @@ mod tests { let (decoded, _) = BooleanBitfield::ssz_decode(&ssz, 0).unwrap(); assert_eq!(original, decoded); } + + #[test] + fn test_bitand() { + let a = BooleanBitfield::from_bytes(&vec![2, 8, 1][..]); + let b = BooleanBitfield::from_bytes(&vec![4, 8, 16][..]); + let c = BooleanBitfield::from_bytes(&vec![6, 8, 17][..]); + assert_eq!(c, a & b); + } }