Skip to main content

reifydb_type/value/container/
bool.rs

1// SPDX-License-Identifier: MIT
2// Copyright (c) 2025 ReifyDB
3
4use std::{
5	fmt::{self, Debug},
6	ops::Deref,
7};
8
9use serde::{Deserialize, Deserializer, Serialize, Serializer};
10
11use crate::{
12	storage::{Cow, DataBitVec, Storage},
13	util::bitvec::BitVec,
14	value::{Value, r#type::Type},
15};
16
17pub struct BoolContainer<S: Storage = Cow> {
18	data: S::BitVec,
19}
20
21impl<S: Storage> Clone for BoolContainer<S> {
22	fn clone(&self) -> Self {
23		Self {
24			data: self.data.clone(),
25		}
26	}
27}
28
29impl<S: Storage> Debug for BoolContainer<S>
30where
31	S::BitVec: Debug,
32{
33	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34		f.debug_struct("BoolContainer").field("data", &self.data).finish()
35	}
36}
37
38impl<S: Storage> PartialEq for BoolContainer<S>
39where
40	S::BitVec: PartialEq,
41{
42	fn eq(&self, other: &Self) -> bool {
43		self.data == other.data
44	}
45}
46
47impl Serialize for BoolContainer<Cow> {
48	fn serialize<Ser: Serializer>(&self, serializer: Ser) -> Result<Ser::Ok, Ser::Error> {
49		#[derive(Serialize)]
50		struct Helper<'a> {
51			data: &'a BitVec,
52		}
53		Helper {
54			data: &self.data,
55		}
56		.serialize(serializer)
57	}
58}
59
60impl<'de> Deserialize<'de> for BoolContainer<Cow> {
61	fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
62		#[derive(Deserialize)]
63		struct Helper {
64			data: BitVec,
65		}
66		let h = Helper::deserialize(deserializer)?;
67		Ok(BoolContainer {
68			data: h.data,
69		})
70	}
71}
72
73impl Deref for BoolContainer<Cow> {
74	type Target = BitVec;
75
76	fn deref(&self) -> &Self::Target {
77		&self.data
78	}
79}
80
81impl BoolContainer<Cow> {
82	pub fn new(data: Vec<bool>) -> Self {
83		Self {
84			data: BitVec::from_slice(&data),
85		}
86	}
87
88	pub fn with_capacity(capacity: usize) -> Self {
89		Self {
90			data: BitVec::with_capacity(capacity),
91		}
92	}
93
94	pub fn from_vec(data: Vec<bool>) -> Self {
95		Self {
96			data: BitVec::from_slice(&data),
97		}
98	}
99}
100
101impl<S: Storage> BoolContainer<S> {
102	pub fn from_parts(data: S::BitVec) -> Self {
103		Self {
104			data,
105		}
106	}
107
108	pub fn len(&self) -> usize {
109		DataBitVec::len(&self.data)
110	}
111
112	pub fn capacity(&self) -> usize {
113		DataBitVec::capacity(&self.data)
114	}
115
116	pub fn is_empty(&self) -> bool {
117		DataBitVec::len(&self.data) == 0
118	}
119
120	pub fn clear(&mut self) {
121		DataBitVec::clear(&mut self.data);
122	}
123
124	pub fn push(&mut self, value: bool) {
125		DataBitVec::push(&mut self.data, value);
126	}
127
128	pub fn push_default(&mut self) {
129		DataBitVec::push(&mut self.data, false);
130	}
131
132	pub fn get(&self, index: usize) -> Option<bool> {
133		if index < self.len() {
134			Some(DataBitVec::get(&self.data, index))
135		} else {
136			None
137		}
138	}
139
140	pub fn is_defined(&self, idx: usize) -> bool {
141		idx < self.len()
142	}
143
144	pub fn is_fully_defined(&self) -> bool {
145		true
146	}
147
148	pub fn data(&self) -> &S::BitVec {
149		&self.data
150	}
151
152	pub fn data_mut(&mut self) -> &mut S::BitVec {
153		&mut self.data
154	}
155
156	pub fn as_string(&self, index: usize) -> String {
157		if index < self.len() {
158			DataBitVec::get(&self.data, index).to_string()
159		} else {
160			"none".to_string()
161		}
162	}
163
164	pub fn get_value(&self, index: usize) -> Value {
165		if index < self.len() {
166			Value::Boolean(DataBitVec::get(&self.data, index))
167		} else {
168			Value::none_of(Type::Boolean)
169		}
170	}
171
172	pub fn extend(&mut self, other: &Self) -> crate::Result<()> {
173		DataBitVec::extend_from(&mut self.data, &other.data);
174		Ok(())
175	}
176
177	pub fn iter(&self) -> impl Iterator<Item = Option<bool>> + '_ {
178		DataBitVec::iter(&self.data).map(|v| Some(v))
179	}
180
181	pub fn into_iter(self) -> impl Iterator<Item = Option<bool>> {
182		let data: Vec<bool> = DataBitVec::iter(&self.data).collect();
183		data.into_iter().map(|v| Some(v))
184	}
185
186	pub fn slice(&self, start: usize, end: usize) -> Self {
187		let count = (end - start).min(self.len().saturating_sub(start));
188		let mut new_data = DataBitVec::spawn(&self.data, count);
189		for i in start..(start + count) {
190			DataBitVec::push(&mut new_data, DataBitVec::get(&self.data, i));
191		}
192		Self {
193			data: new_data,
194		}
195	}
196
197	pub fn filter(&mut self, mask: &S::BitVec) {
198		let mut new_data = DataBitVec::spawn(&self.data, DataBitVec::count_ones(mask));
199
200		for (i, keep) in DataBitVec::iter(mask).enumerate() {
201			if keep && i < self.len() {
202				DataBitVec::push(&mut new_data, DataBitVec::get(&self.data, i));
203			}
204		}
205
206		self.data = new_data;
207	}
208
209	pub fn reorder(&mut self, indices: &[usize]) {
210		let mut new_data = DataBitVec::spawn(&self.data, indices.len());
211
212		for &idx in indices {
213			if idx < self.len() {
214				DataBitVec::push(&mut new_data, DataBitVec::get(&self.data, idx));
215			} else {
216				DataBitVec::push(&mut new_data, false);
217			}
218		}
219
220		self.data = new_data;
221	}
222
223	pub fn take(&self, num: usize) -> Self {
224		Self {
225			data: DataBitVec::take(&self.data, num),
226		}
227	}
228}
229
230impl Default for BoolContainer<Cow> {
231	fn default() -> Self {
232		Self::with_capacity(0)
233	}
234}
235
236#[cfg(test)]
237pub mod tests {
238	use super::*;
239
240	#[test]
241	fn test_new() {
242		let data = vec![true, false, true];
243		let container = BoolContainer::new(data.clone());
244
245		assert_eq!(container.len(), 3);
246		assert_eq!(container.get(0), Some(true));
247		assert_eq!(container.get(1), Some(false));
248		assert_eq!(container.get(2), Some(true));
249	}
250
251	#[test]
252	fn test_from_vec() {
253		let data = vec![true, false, true];
254		let container = BoolContainer::from_vec(data);
255
256		assert_eq!(container.len(), 3);
257		assert_eq!(container.get(0), Some(true));
258		assert_eq!(container.get(1), Some(false));
259		assert_eq!(container.get(2), Some(true));
260
261		// All should be defined
262		for i in 0..3 {
263			assert!(container.is_defined(i));
264		}
265	}
266
267	#[test]
268	fn test_with_capacity() {
269		let container = BoolContainer::with_capacity(10);
270		assert_eq!(container.len(), 0);
271		assert!(container.is_empty());
272		assert!(container.capacity() >= 10);
273	}
274
275	#[test]
276	fn test_push() {
277		let mut container = BoolContainer::with_capacity(3);
278
279		container.push(true);
280		container.push(false);
281		container.push_default();
282
283		assert_eq!(container.len(), 3);
284		assert_eq!(container.get(0), Some(true));
285		assert_eq!(container.get(1), Some(false));
286		assert_eq!(container.get(2), Some(false)); // default pushes false
287
288		assert!(container.is_defined(0));
289		assert!(container.is_defined(1));
290		assert!(container.is_defined(2));
291	}
292
293	#[test]
294	fn test_extend() {
295		let mut container1 = BoolContainer::from_vec(vec![true, false]);
296		let container2 = BoolContainer::from_vec(vec![false, true]);
297
298		container1.extend(&container2).unwrap();
299
300		assert_eq!(container1.len(), 4);
301		assert_eq!(container1.get(0), Some(true));
302		assert_eq!(container1.get(1), Some(false));
303		assert_eq!(container1.get(2), Some(false));
304		assert_eq!(container1.get(3), Some(true));
305	}
306
307	#[test]
308	fn test_iter() {
309		let data = vec![true, false, true];
310		let container = BoolContainer::new(data);
311
312		let collected: Vec<Option<bool>> = container.iter().collect();
313		assert_eq!(collected, vec![Some(true), Some(false), Some(true)]);
314	}
315
316	#[test]
317	fn test_slice() {
318		let container = BoolContainer::from_vec(vec![true, false, true, false]);
319		let sliced = container.slice(1, 3);
320
321		assert_eq!(sliced.len(), 2);
322		assert_eq!(sliced.get(0), Some(false));
323		assert_eq!(sliced.get(1), Some(true));
324	}
325
326	#[test]
327	fn test_filter() {
328		use crate::util::bitvec::BitVec;
329		let mut container = BoolContainer::from_vec(vec![true, false, true, false]);
330		let mask = BitVec::from_slice(&[true, false, true, false]);
331
332		container.filter(&mask);
333
334		assert_eq!(container.len(), 2);
335		assert_eq!(container.get(0), Some(true));
336		assert_eq!(container.get(1), Some(true));
337	}
338
339	#[test]
340	fn test_reorder() {
341		let mut container = BoolContainer::from_vec(vec![true, false, true]);
342		let indices = [2, 0, 1];
343
344		container.reorder(&indices);
345
346		assert_eq!(container.len(), 3);
347		assert_eq!(container.get(0), Some(true)); // was index 2
348		assert_eq!(container.get(1), Some(true)); // was index 0
349		assert_eq!(container.get(2), Some(false)); // was index 1
350	}
351
352	#[test]
353	fn test_reorder_with_out_of_bounds() {
354		let mut container = BoolContainer::from_vec(vec![true, false]);
355		let indices = [1, 5, 0]; // index 5 is out of bounds
356
357		container.reorder(&indices);
358
359		assert_eq!(container.len(), 3);
360		assert_eq!(container.get(0), Some(false)); // was index 1
361		assert_eq!(container.get(1), Some(false)); // out of bounds -> default (false)
362		assert_eq!(container.get(2), Some(true)); // was index 0
363	}
364
365	#[test]
366	fn test_default() {
367		let container = BoolContainer::default();
368		assert_eq!(container.len(), 0);
369		assert!(container.is_empty());
370	}
371}