1#![allow(dead_code, unused_variables)]
2
3use std::fmt;
4
5use serde::{Deserialize, Serialize};
6
7const ONE_BYTE_BITS_COUNT: i8 = 8;
10
11#[derive(Clone, Debug)]
14pub struct OutOfRangeError {
15 pub bitarray_size: i64,
16 pub bitarray_position: i64,
17}
18
19impl OutOfRangeError {
20 pub fn new(bitarray_size: i64, bitarray_position: i64) -> Self {
24 Self {
25 bitarray_size,
26 bitarray_position,
27 }
28 }
29}
30
31impl fmt::Display for OutOfRangeError {
32 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
33 write!(
34 f,
35 "Given position: {} is out of the bitarray size {}.",
36 self.bitarray_position, self.bitarray_size
37 )
38 }
39}
40
41#[derive(Debug, Serialize, Deserialize)]
59pub struct BitArray {
60 pub size: i64,
61 pub bit_array: Vec<u8>,
62}
63
64impl BitArray {
65 pub fn new(size: i64) -> Self {
69 let _capacity: usize = (size / ONE_BYTE_BITS_COUNT as i64) as usize + 1;
71
72 let mut bit_array: Vec<u8> = Vec::with_capacity(_capacity);
73
74 for _ in 0.._capacity {
76 bit_array.push(0);
77 }
78
79 Self { size, bit_array }
80 }
81
82 fn calc_vec_position(position: i64) -> usize {
85 (position / ONE_BYTE_BITS_COUNT as i64) as usize
86 }
87
88 fn calc_byte_offset(position: i64) -> u8 {
91 let _pow: i64 = position % ONE_BYTE_BITS_COUNT as i64;
92
93 2u64.pow(_pow as u32) as u8
94 }
95
96 pub fn set(&mut self, position: i64, flag: bool) -> Result<(), OutOfRangeError> {
98 if position >= self.size {
99 Err(OutOfRangeError::new(self.size, position as i64))
100 } else {
101 let vec_position: usize = Self::calc_vec_position(position);
102 let byte_offset: u8 = Self::calc_byte_offset(position);
103
104 if flag {
105 self.bit_array[vec_position] |= byte_offset;
106 } else {
107 self.bit_array[vec_position] &= !byte_offset;
108 }
109
110 Ok(())
111 }
112 }
113
114 pub fn get(&self, position: i64) -> Result<bool, OutOfRangeError> {
116 if position >= self.size {
117 Err(OutOfRangeError::new(self.size, position))
118 } else {
119 let vec_position: usize = Self::calc_vec_position(position);
120 let byte_offset: u8 = Self::calc_byte_offset(position);
121
122 Ok(self.bit_array[vec_position] == (self.bit_array[vec_position] | byte_offset))
123 }
124 }
125}
126
127#[cfg(test)]
128mod tests {
129 use super::{BitArray, ONE_BYTE_BITS_COUNT};
130
131 #[test]
132 fn test_init_bitarray() {
133 let bitarray_size: i64 = 10;
139
140 let bitarray: BitArray = BitArray::new(bitarray_size);
141
142 assert_eq!(
143 bitarray.bit_array.len(),
144 (bitarray_size / ONE_BYTE_BITS_COUNT as i64) as usize + 1
145 );
146 assert_eq!(bitarray.bit_array.len(), 2);
147 }
148
149 #[test]
150 fn test_bitarray_set_true() {
151 let bitarray_size: i64 = 10;
152 let bitarray_position: i64 = 9;
153
154 let mut bitarray: BitArray = BitArray::new(bitarray_size);
155
156 let success: bool = match bitarray.set(bitarray_position, true) {
157 Ok(_) => true,
158 Err(_) => false,
159 };
160
161 assert!(success);
162 }
163
164 #[test]
165 fn test_bitarray_set_with_error() {
166 let bitarray_size: i64 = 10;
167 let bitarray_position: i64 = 10;
168
169 let mut bitarray: BitArray = BitArray::new(bitarray_size);
170
171 let success: bool = match bitarray.set(bitarray_position, true) {
172 Ok(_) => false,
173 Err(err) => {
174 err.bitarray_position == 10
175 && err.bitarray_size == 10
176 && format!("{}", err) == "Given position: 10 is out of the bitarray size 10."
177 }
178 };
179
180 assert!(success);
181 }
182
183 #[test]
184 fn test_bitarray_get_with_error() {
185 let bitarray_size: i64 = 10;
186 let bitarray_position: i64 = 10;
187
188 let bitarray: BitArray = BitArray::new(bitarray_size);
189
190 let success: bool = match bitarray.get(bitarray_position) {
191 Ok(_) => false,
192 Err(err) => {
193 err.bitarray_position == 10
194 && err.bitarray_size == 10
195 && format!("{}", err) == "Given position: 10 is out of the bitarray size 10."
196 }
197 };
198
199 assert!(success);
200 }
201
202 #[test]
203 fn test_bit_array_get_set() {
204 let bitarray_size: i64 = 74845;
205
206 let mut bitarray: BitArray = BitArray::new(bitarray_size);
207
208 for bitarray_position in 0..bitarray_size - 1 {
209 assert!(!bitarray.get(bitarray_position).unwrap());
210 }
211
212 for bitarray_position in 0..bitarray_size {
213 bitarray.set(bitarray_position, true).unwrap();
214
215 assert!(bitarray.get(bitarray_position).unwrap());
216 }
217
218 for bitarray_position in 0..bitarray_size - 1 {
219 assert!(bitarray.get(bitarray_position).unwrap());
220 }
221
222 for bitarray_position in 0..bitarray_size {
223 bitarray.set(bitarray_position, false).unwrap();
224
225 assert!(!bitarray.get(bitarray_position).unwrap());
226 }
227
228 for bitarray_position in 0..bitarray_size - 1 {
229 assert!(!bitarray.get(bitarray_position).unwrap());
230 }
231 }
232}