devol_accounts_kit/utils/
bitmask.rs

1use std::ops::{BitAnd, BitOr, BitXor, Not, Shl};
2use serde::{Deserialize, Serialize};
3
4#[derive(Copy, Clone, PartialOrd, PartialEq, Debug, Serialize, Deserialize)]
5pub struct BitMask<T>(pub T);
6
7impl<T> BitMask<T>
8    where
9        T: BitAnd<Output = T> + BitOr<Output = T> + BitXor<Output = T> + Not<Output = T> + Shl<u8, Output = T> + From<u8> + Copy + PartialEq,
10{
11    #[inline(always)]
12    pub fn set(&mut self, index: u8, value: bool) {
13        if value {
14            self.0 = self.0 | (T::from(1) << index);
15        } else {
16            self.0 = self.0 & !(T::from(1) << index);
17        }
18    }
19
20    #[inline(always)]
21    pub fn get(&self, index: u8) -> bool {
22        (self.0 & (T::from(1) << index)) != T::from(0)
23    }
24    #[allow(dead_code)]
25    #[inline(always)]
26    fn value(&self) -> T {
27        self.0
28    }
29}
30
31#[cfg(test)]
32mod tests {
33    use super::*;
34
35    #[test]
36    fn test_set_get_u32() {
37        let mut mask = BitMask(0u32);
38        mask.set(0, true);
39        assert!(mask.get(0));
40        assert_eq!(mask.value(), 1);
41
42        mask.set(31, true);
43        assert!(mask.get(31));
44        assert_eq!(mask.value(), 0x80000001);
45
46        mask.set(0, false);
47        assert!(!mask.get(0));
48        assert_eq!(mask.value(), 0x80000000);
49    }
50
51    #[test]
52    fn test_set_get_u64() {
53        let mut mask = BitMask(0u64);
54        mask.set(0, true);
55        assert!(mask.get(0));
56        assert_eq!(mask.value(), 1);
57
58        mask.set(63, true);
59        assert!(mask.get(63));
60        assert_eq!(mask.value(), 0x8000000000000001);
61
62        mask.set(0, false);
63        assert!(!mask.get(0));
64        assert_eq!(mask.value(), 0x8000000000000000);
65    }
66
67    #[test]
68    fn test_multiple_flags_u32() {
69        let mut mask = BitMask(0u32);
70        mask.set(0, true);
71        mask.set(15, true);
72        mask.set(31, true);
73        assert!(mask.get(0));
74        assert!(mask.get(15));
75        assert!(mask.get(31));
76        assert_eq!(mask.value(), 0x80008001);
77    }
78
79    #[test]
80    fn test_multiple_flags_u64() {
81        let mut mask = BitMask(0u64);
82        mask.set(0, true);
83        mask.set(31, true);
84        mask.set(63, true);
85        assert!(mask.get(0));
86        assert!(mask.get(31));
87        assert!(mask.get(63));
88        assert_eq!(mask.value(), 0x8000000080000001);
89    }
90}