Skip to main content

equanetwork_math/
bitmap.rs

1#[cfg(feature = "wasm")]
2use equanetwork_macros::wasm_expose;
3
4#[cfg(feature = "wasm")]
5use wasm_bindgen::prelude::*;
6
7#[cfg(feature = "wasm")]
8use core::fmt::{Debug, Formatter};
9
10#[cfg(feature = "wasm")]
11#[wasm_bindgen]
12extern "C" {
13    #[wasm_bindgen(typescript_type = "Buffer")]
14    pub type Bitmap;
15}
16
17#[cfg(feature = "wasm")]
18impl Debug for Bitmap {
19    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
20        write!(f, "{:?}", JsValue::from(self))
21    }
22}
23
24#[cfg(feature = "wasm")]
25impl From<Bitmap> for [u8; 32] {
26    fn from(bitmap: Bitmap) -> Self {
27        let value = JsValue::from(bitmap);
28        serde_wasm_bindgen::from_value(value).expect("Invalid bitmap")
29    }
30}
31
32#[cfg(feature = "wasm")]
33impl From<[u8; 32]> for Bitmap {
34    fn from(bitmap: [u8; 32]) -> Self {
35        Bitmap {
36            obj: serde_wasm_bindgen::to_value(&bitmap).expect("Invalid bitmap"),
37        }
38    }
39}
40
41#[cfg(feature = "wasm")]
42#[cfg_attr(feature = "wasm", wasm_expose)]
43pub fn bitmap_add(bitmap: Bitmap, value: u8) -> Bitmap {
44    let mut bitmap = bitmap.into();
45    bitmap_set(&mut bitmap, value);
46    bitmap.into()
47}
48
49#[cfg(feature = "wasm")]
50#[cfg_attr(feature = "wasm", wasm_expose)]
51pub fn bitmap_remove(bitmap: Bitmap, value: u8) -> Bitmap {
52    let mut bitmap = bitmap.into();
53    bitmap_unset(&mut bitmap, value);
54    bitmap.into()
55}
56
57#[cfg(feature = "wasm")]
58#[cfg_attr(feature = "wasm", wasm_expose)]
59pub fn bitmap_has(bitmap: Bitmap, value: u8) -> bool {
60    let bitmap = bitmap.into();
61    bitmap_contains(&bitmap, value)
62}
63
64pub fn bitmap_set(bitmap: &mut [u8; 32], value: u8) {
65    let byte_index = value / 8;
66    let bit_index = value % 8;
67    bitmap[byte_index as usize] |= 1 << bit_index;
68}
69
70pub fn bitmap_unset(bitmap: &mut [u8; 32], value: u8) {
71    let byte_index = value / 8;
72    let bit_index = value % 8;
73    bitmap[byte_index as usize] &= !(1 << bit_index);
74}
75
76pub fn bitmap_contains(bitmap: &[u8; 32], value: u8) -> bool {
77    let byte_index = value / 8;
78    let bit_index = value % 8;
79    bitmap[byte_index as usize] & (1 << bit_index) != 0
80}
81
82#[cfg(test)]
83mod tests {
84    use super::*;
85
86    #[test]
87    fn test_contains_bitmap() {
88        let empty = [0u8; 32];
89        let full = [255u8; 32];
90        let odd_only = [85u8; 32];
91        for i in 0..=255 {
92            assert!(!bitmap_contains(&empty, i));
93            assert!(bitmap_contains(&full, i));
94            assert_eq!(bitmap_contains(&odd_only, i), i & 1 == 0);
95        }
96    }
97
98    #[test]
99    fn test_set_bitmap() {
100        let mut bitmap = [0u8; 32];
101        for i in 0..=255 {
102            if i & 1 == 0 {
103                bitmap_set(&mut bitmap, i);
104            }
105        }
106        assert_eq!(bitmap, [85u8; 32]);
107    }
108
109    #[test]
110    fn test_unset_bitmap() {
111        let mut bitmap = [255u8; 32];
112        for i in 0..=255 {
113            if i & 1 != 0 {
114                bitmap_unset(&mut bitmap, i);
115            }
116        }
117        assert_eq!(bitmap, [85u8; 32]);
118    }
119}