1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//! Implementations of formating methods for `Bitmap`, including [`Debug`].
use alloc::{string::{String, ToString}, format};
use crate::bitmap::*;
impl<const BYTES: usize> core::fmt::Display for Bitmap<BYTES> {
/// Formats a bitmap. Only shows the last 2 bytes if the bitmap is longer.
/// The bytes will be separated by space `' '`.
///
/// The bits will be arranged from right to left. If the bitmap is longer than
/// 2 bytes, a `"..."` will show on the left.
/// On the very left, a bracket tells the bit length of the map (in a form
/// like `"[N bits]"`). A space `' '` will be between the bit contents and this
/// bracket.
///
/// # Examples
/// ```
/// use cbitmap::bitmap::*;
///
/// let mut map: Bitmap<3> = 0.into();
/// map.set(0);
/// map.set(8);
/// let str = &format!("{map}");
/// assert_eq!(str, "[24 bits] ...00000001 00000001");
/// ```
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mut contents = String::new();
contents.push_str(&format!("[{} bits] ", BYTES * 8));
let size = 2.min(BYTES);
if BYTES > size {
contents.push_str("...")
}
for i in 0..size {
if i > 0 {
contents.push_str(" ");
}
contents.push_str(&format!("{:08b}", self.__copy_u8(size - i - 1)));
}
write!(f, "{contents}")
}
}
impl<const BYTES: usize> core::fmt::Debug for Bitmap<BYTES> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let mut contents = String::new();
let size = 2.min(BYTES);
if BYTES > size {
contents.push_str("...")
}
for i in 0..size {
if i > 0 {
contents.push_str(" ");
}
contents.push_str(&format!("{:08b}", self.__copy_u8(size - i - 1)));
}
f.debug_struct("Bitmap")
.field("#bytes", &BYTES)
.field("#bits", &(BYTES * 8))
.field("bits", &contents)
.finish()
}
}
impl<const BYTES: usize> Bitmap<BYTES> {
/// Format a range of bits into a [`Option<String>`].
///
/// An array of `'0'`/`'1'` will show in the String. The bits are separated
/// by `' '` at the edge of 2 bytes.
///
/// # Return
/// [`None`] if the range is invalid (out of the bitmap, or length is less
/// than 0), [`Some(String)`] otherwise.
///
/// # Examples
/// ```
/// use cbitmap::bitmap::*;
///
/// let map: Bitmap<2> = 0b_011_11001100.into();
/// let string = map.range_to_string(2, 11).unwrap();
/// assert_eq!(&string, "011 110011");
///
/// assert!(map.range_to_string(0, 100).is_none());
/// assert!(map.range_to_string(100, 101).is_none());
/// assert!(map.range_to_string(2, 1).is_none());
/// ```
pub fn range_to_string(&self, start: usize, end: usize) -> Option<String> {
if start >= end || __out_bound(BYTES, start) || __out_bound(BYTES, end - 1) {
return None;
}
let mut contents = String::new();
let mut i = end - 1;
while __idx_get_byte(i) > __idx_get_byte(start) {
let bit = __idx_get_bit(i);
match bit {
7 => {
contents.push_str(&format!("{:08b}", self.__copy_u8(__idx_get_byte(i))));
contents.push_str(" ");
i -= 8;
}
_ => {
contents.push_str(&self.get_01(i).to_string());
if bit == 0 {
contents.push_str(" ");
}
i -= 1;
}
}
}
while i > start {
contents.push_str(&self.get_01(i).to_string());
i -= 1;
}
contents.push_str(&self.get_01(i).to_string());
Some(contents)
}
}