lsp_primitives/lsps0/
util.rs1use anyhow::Context;
2use std::str::FromStr;
8
9pub const LSP_SERVER_FEATURE_BIT: usize = 729;
10
11pub struct FeatureBitMap(Vec<u8>);
12
13impl FromStr for FeatureBitMap {
14 type Err = anyhow::Error;
15
16 fn from_str(s: &str) -> Result<Self, Self::Err> {
17 let hex = hex::decode(s).context("Failed to parse feature-bitmap")?;
18 Ok(FeatureBitMap(hex))
19 }
20}
21
22impl AsRef<[u8]> for &FeatureBitMap {
23 fn as_ref(&self) -> &[u8] {
24 &self.0
25 }
26}
27
28impl FeatureBitMap {
29 pub fn new(bitmap: Vec<u8>) -> Self {
30 FeatureBitMap(bitmap)
31 }
32}
33
34pub fn is_feature_bit_enabled<T: AsRef<[u8]>>(bitmap: T, index: usize) -> bool {
36 let bm = bitmap.as_ref();
37 let n_bytes = bm.len();
38 let (byte_index, bit_index) = (index / 8, index % 8);
39
40 if byte_index >= n_bytes {
42 return false;
43 }
44
45 let selected_byte = bm[n_bytes - 1 - byte_index];
46 let bit_mask = 1u8 << (bit_index);
47
48 (selected_byte & bit_mask) != 0
49}
50
51#[cfg(test)]
52mod test {
53 use super::*;
54
55 #[test]
56 fn test_parse_bitmap() {
57 let feature_bitmap_00 = FeatureBitMap::from_str("01").unwrap();
59 let feature_bitmap_01 = FeatureBitMap::from_str("02").unwrap();
60 let feature_bitmap_02 = FeatureBitMap::from_str("04").unwrap();
61 let feature_bitmap_03 = FeatureBitMap::from_str("08").unwrap();
62 let feature_bitmap_04 = FeatureBitMap::from_str("10").unwrap();
63 let feature_bitmap_05 = FeatureBitMap::from_str("20").unwrap();
64 let feature_bitmap_06 = FeatureBitMap::from_str("40").unwrap();
65 let feature_bitmap_07 = FeatureBitMap::from_str("80").unwrap();
66
67 assert!(is_feature_bit_enabled(&feature_bitmap_00, 0));
69 assert!(is_feature_bit_enabled(&feature_bitmap_01, 1));
70 assert!(is_feature_bit_enabled(&feature_bitmap_02, 2));
71 assert!(is_feature_bit_enabled(&feature_bitmap_03, 3));
72 assert!(is_feature_bit_enabled(&feature_bitmap_04, 4));
73 assert!(is_feature_bit_enabled(&feature_bitmap_05, 5));
74 assert!(is_feature_bit_enabled(&feature_bitmap_06, 6));
75 assert!(is_feature_bit_enabled(&feature_bitmap_07, 7));
76
77 assert!(!is_feature_bit_enabled(&feature_bitmap_01, 0));
79 assert!(!is_feature_bit_enabled(&feature_bitmap_01, 2));
80 assert!(!is_feature_bit_enabled(&feature_bitmap_01, 3));
81 assert!(!is_feature_bit_enabled(&feature_bitmap_01, 4));
82 assert!(!is_feature_bit_enabled(&feature_bitmap_01, 5));
83 assert!(!is_feature_bit_enabled(&feature_bitmap_01, 6));
84 assert!(!is_feature_bit_enabled(&feature_bitmap_01, 7));
85 assert!(!is_feature_bit_enabled(&feature_bitmap_01, 8));
86 assert!(!is_feature_bit_enabled(&feature_bitmap_01, 9));
87
88 assert!(!is_feature_bit_enabled(&feature_bitmap_01, 1000));
89 }
90
91 #[test]
92 fn test_lsps_option_enabled_bitmap() {
93 let data = "0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
96 let bitmap = FeatureBitMap::from_str(data).unwrap();
97
98 assert!(is_feature_bit_enabled(&bitmap, LSP_SERVER_FEATURE_BIT));
100
101 assert!(!is_feature_bit_enabled(&bitmap, 728));
103 assert!(!is_feature_bit_enabled(&bitmap, 730));
104 }
105}