devol_accounts_kit/utils/
bitmask.rs1use 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}