@@ -5,6 +5,42 @@ use core::fmt;
55use serde_json:: Value ;
66use std:: str:: FromStr ;
77
8+ /// Checks if the feature bit is set in the provided bitmap.
9+ /// Returns true if the `feature_bit` is set in the `bitmap`. Returns false if
10+ /// the `feature_bit` is unset or our ouf bounds.
11+ ///
12+ /// # Arguments
13+ ///
14+ /// * `bitmap`: A slice of bytes representing the feature bitmap.
15+ /// * `feature_bit`: The 0-based index of the bit to check across the bitmap.
16+ ///
17+ pub fn is_feature_bit_set ( bitmap : & [ u8 ] , feature_bit : usize ) -> bool {
18+ let byte_index = feature_bit >> 3 ; // Equivalent to feature_bit / 8
19+ let bit_index = feature_bit & 7 ; // Equivalent to feature_bit % 8
20+
21+ if let Some ( & target_byte) = bitmap. get ( byte_index) {
22+ let mask = 1 << bit_index;
23+ ( target_byte & mask) != 0
24+ } else {
25+ false
26+ }
27+ }
28+
29+ /// Returns a single feature_bit in hex representation, least-significant bit
30+ /// first.
31+ ///
32+ /// # Arguments
33+ ///
34+ /// * `feature_bit`: The 0-based index of the bit to check across the bitmap.
35+ ///
36+ pub fn feature_bit_to_hex ( feature_bit : usize ) -> String {
37+ let byte_index = feature_bit >> 3 ; // Equivalent to feature_bit / 8
38+ let mask = 1 << ( feature_bit & 7 ) ; // Equivalent to feature_bit % 8
39+ let mut map = vec ! [ 0u8 ; byte_index + 1 ] ;
40+ map[ 0 ] |= mask; // least-significant bit first ordering.
41+ hex:: encode ( & map)
42+ }
43+
844/// Errors that can occur when unwrapping payload data
945#[ derive( Debug , Clone , PartialEq ) ]
1046pub enum UnwrapError {
@@ -131,4 +167,81 @@ mod tests {
131167 Some ( UnwrapError :: InvalidPublicKey ( _) )
132168 ) ) ;
133169 }
170+
171+ #[ test]
172+ fn test_basic_bit_checks ( ) {
173+ // Example bitmap:
174+ // Byte 0: 0b10100101 (165) -> Bits 0, 2, 5, 7 set
175+ // Byte 1: 0b01101010 (106) -> Bits 1, 3, 5, 6 set (indices 9, 11, 13, 14)
176+ let bitmap: & [ u8 ] = & [ 0b10100101 , 0b01101010 ] ;
177+
178+ // Check bits in byte 0 (indices 0-7)
179+ assert_eq ! ( is_feature_bit_set( bitmap, 0 ) , true ) ; // Bit 0
180+ assert_eq ! ( is_feature_bit_set( bitmap, 1 ) , false ) ; // Bit 1
181+ assert_eq ! ( is_feature_bit_set( bitmap, 2 ) , true ) ; // Bit 2
182+ assert_eq ! ( is_feature_bit_set( bitmap, 3 ) , false ) ; // Bit 3
183+ assert_eq ! ( is_feature_bit_set( bitmap, 4 ) , false ) ; // Bit 4
184+ assert_eq ! ( is_feature_bit_set( bitmap, 5 ) , true ) ; // Bit 5
185+ assert_eq ! ( is_feature_bit_set( bitmap, 6 ) , false ) ; // Bit 6
186+ assert_eq ! ( is_feature_bit_set( bitmap, 7 ) , true ) ; // Bit 7
187+
188+ // Check bits in byte 1 (indices 8-15)
189+ assert_eq ! ( is_feature_bit_set( bitmap, 8 ) , false ) ; // Bit 8 (Byte 1, bit 0)
190+ assert_eq ! ( is_feature_bit_set( bitmap, 9 ) , true ) ; // Bit 9 (Byte 1, bit 1)
191+ assert_eq ! ( is_feature_bit_set( bitmap, 10 ) , false ) ; // Bit 10 (Byte 1, bit 2)
192+ assert_eq ! ( is_feature_bit_set( bitmap, 11 ) , true ) ; // Bit 11 (Byte 1, bit 3)
193+ assert_eq ! ( is_feature_bit_set( bitmap, 12 ) , false ) ; // Bit 12 (Byte 1, bit 4)
194+ assert_eq ! ( is_feature_bit_set( bitmap, 13 ) , true ) ; // Bit 13 (Byte 1, bit 5)
195+ assert_eq ! ( is_feature_bit_set( bitmap, 14 ) , true ) ; // Bit 14 (Byte 1, bit 6)
196+ assert_eq ! ( is_feature_bit_set( bitmap, 15 ) , false ) ; // Bit 15 (Byte 1, bit 7)
197+ }
198+
199+ #[ test]
200+ fn test_out_of_bounds ( ) {
201+ let bitmap: & [ u8 ] = & [ 0b11111111 , 0b00000000 ] ; // 16 bits total
202+
203+ assert_eq ! ( is_feature_bit_set( bitmap, 15 ) , false ) ; // Last valid bit (is 0)
204+ assert_eq ! ( is_feature_bit_set( bitmap, 16 ) , false ) ; // Out of bounds
205+ assert_eq ! ( is_feature_bit_set( bitmap, 100 ) , false ) ; // Way out of bounds
206+ }
207+
208+ #[ test]
209+ fn test_empty_bitmap ( ) {
210+ let bitmap: & [ u8 ] = & [ ] ;
211+ assert_eq ! ( is_feature_bit_set( bitmap, 0 ) , false ) ;
212+ assert_eq ! ( is_feature_bit_set( bitmap, 8 ) , false ) ;
213+ }
214+
215+ #[ test]
216+ fn test_feature_to_hex_bit_0_be ( ) {
217+ // Bit 0 is in Byte 0 (LE index). num_bytes=1. BE index = 1-1-0=0.
218+ // Expected map: [0x01]
219+ let feature_hex = feature_bit_to_hex ( 0 ) ;
220+ assert_eq ! ( feature_hex, "01" ) ;
221+ assert ! ( is_feature_bit_set( & hex:: decode( feature_hex) . unwrap( ) , 0 ) ) ;
222+ }
223+
224+ #[ test]
225+ fn test_feature_to_hex_bit_8_be ( ) {
226+ // Bit 8 is in Byte 1 (LE index). num_bytes=2. BE index = 2-1-1=0.
227+ // Mask is 0x01 for bit 0 within its byte.
228+ // Expected map: [0x01, 0x00] (Byte for 8-15 first, then 0-7)
229+ let feature_hex = feature_bit_to_hex ( 8 ) ;
230+ let mut decoded = hex:: decode ( & feature_hex) . unwrap ( ) ;
231+ decoded. reverse ( ) ;
232+ assert_eq ! ( feature_hex, "0100" ) ;
233+ assert ! ( is_feature_bit_set( & decoded, 8 ) ) ;
234+ }
235+
236+ #[ test]
237+ fn test_feature_to_hex_bit_27_be ( ) {
238+ // Bit 27 is in Byte 3 (LE index). num_bytes=4. BE index = 4-1-3=0.
239+ // Mask is 0x08 for bit 3 within its byte.
240+ // Expected map: [0x08, 0x00, 0x00, 0x00] (Byte for 24-31 first)
241+ let feature_hex = feature_bit_to_hex ( 27 ) ;
242+ let mut decoded = hex:: decode ( & feature_hex) . unwrap ( ) ;
243+ decoded. reverse ( ) ;
244+ assert_eq ! ( feature_hex, "08000000" ) ;
245+ assert ! ( is_feature_bit_set( & decoded, 27 ) ) ;
246+ }
134247}
0 commit comments