Skip to main content

reifydb_type/value/container/
number.rs

1// SPDX-License-Identifier: MIT
2// Copyright (c) 2025 ReifyDB
3
4use std::{
5	any::TypeId,
6	fmt::{self, Debug},
7	mem::{forget, transmute_copy},
8	ops::Deref,
9	result::Result as StdResult,
10};
11
12use serde::{Deserialize, Deserializer, Serialize, Serializer};
13
14use crate::{
15	Result,
16	storage::{Cow, DataBitVec, DataVec, Storage},
17	util::cowvec::CowVec,
18	value::{
19		Value,
20		Value::{Int1, Int2, Int4, Int8, Int16, Uint1, Uint2, Uint4, Uint8, Uint16},
21		decimal::Decimal,
22		int::Int,
23		is::IsNumber,
24		ordered_f32::OrderedF32,
25		ordered_f64::OrderedF64,
26		r#type::Type,
27		uint::Uint,
28	},
29};
30
31pub struct NumberContainer<T, S: Storage = Cow>
32where
33	T: IsNumber,
34{
35	data: S::Vec<T>,
36}
37
38impl<T: IsNumber, S: Storage> Clone for NumberContainer<T, S> {
39	fn clone(&self) -> Self {
40		Self {
41			data: self.data.clone(),
42		}
43	}
44}
45
46impl<T: IsNumber + Debug, S: Storage> Debug for NumberContainer<T, S>
47where
48	S::Vec<T>: Debug,
49{
50	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51		f.debug_struct("NumberContainer").field("data", &self.data).finish()
52	}
53}
54
55impl<T: IsNumber, S: Storage> PartialEq for NumberContainer<T, S>
56where
57	S::Vec<T>: PartialEq,
58{
59	fn eq(&self, other: &Self) -> bool {
60		self.data == other.data
61	}
62}
63
64impl<T: IsNumber + Serialize> Serialize for NumberContainer<T, Cow> {
65	fn serialize<Ser: Serializer>(&self, serializer: Ser) -> StdResult<Ser::Ok, Ser::Error> {
66		#[derive(Serialize)]
67		struct Helper<'a, T: Clone + PartialEq + Serialize> {
68			data: &'a CowVec<T>,
69		}
70		Helper {
71			data: &self.data,
72		}
73		.serialize(serializer)
74	}
75}
76
77impl<'de, T: IsNumber + Deserialize<'de>> Deserialize<'de> for NumberContainer<T, Cow> {
78	fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
79		#[derive(Deserialize)]
80		struct Helper<T: Clone + PartialEq> {
81			data: CowVec<T>,
82		}
83		let h = Helper::deserialize(deserializer)?;
84		Ok(NumberContainer {
85			data: h.data,
86		})
87	}
88}
89
90impl<T: IsNumber, S: Storage> Deref for NumberContainer<T, S> {
91	type Target = [T];
92
93	fn deref(&self) -> &Self::Target {
94		self.data.as_slice()
95	}
96}
97
98impl<T> NumberContainer<T, Cow>
99where
100	T: IsNumber + Clone + Debug + Default,
101{
102	pub fn new(data: Vec<T>) -> Self {
103		Self {
104			data: CowVec::new(data),
105		}
106	}
107
108	pub fn with_capacity(capacity: usize) -> Self {
109		Self {
110			data: CowVec::with_capacity(capacity),
111		}
112	}
113
114	pub fn from_vec(data: Vec<T>) -> Self {
115		Self {
116			data: CowVec::new(data),
117		}
118	}
119}
120
121impl<T, S: Storage> NumberContainer<T, S>
122where
123	T: IsNumber + Clone + Debug + Default,
124{
125	pub fn from_parts(data: S::Vec<T>) -> Self {
126		Self {
127			data,
128		}
129	}
130
131	pub fn len(&self) -> usize {
132		DataVec::len(&self.data)
133	}
134
135	pub fn capacity(&self) -> usize {
136		DataVec::capacity(&self.data)
137	}
138
139	pub fn is_empty(&self) -> bool {
140		DataVec::is_empty(&self.data)
141	}
142
143	pub fn clear(&mut self) {
144		DataVec::clear(&mut self.data);
145	}
146
147	pub fn push(&mut self, value: T) {
148		DataVec::push(&mut self.data, value);
149	}
150
151	pub fn push_default(&mut self) {
152		DataVec::push(&mut self.data, T::default());
153	}
154
155	pub fn get(&self, index: usize) -> Option<&T> {
156		if index < self.len() {
157			DataVec::get(&self.data, index)
158		} else {
159			None
160		}
161	}
162
163	pub fn is_defined(&self, idx: usize) -> bool {
164		idx < self.len()
165	}
166
167	pub fn is_fully_defined(&self) -> bool {
168		true
169	}
170
171	pub fn data(&self) -> &S::Vec<T> {
172		&self.data
173	}
174
175	pub fn data_mut(&mut self) -> &mut S::Vec<T> {
176		&mut self.data
177	}
178
179	pub fn as_string(&self, index: usize) -> String {
180		if index < self.len() {
181			self.data[index].to_string()
182		} else {
183			"none".to_string()
184		}
185	}
186
187	pub fn get_value(&self, index: usize) -> Value
188	where
189		T: 'static,
190	{
191		if index < self.len() {
192			let value = self.data[index].clone();
193
194			if TypeId::of::<T>() == TypeId::of::<f32>() {
195				let f_val = unsafe { transmute_copy::<T, f32>(&value) };
196				OrderedF32::try_from(f_val).map(Value::Float4).unwrap_or(Value::None {
197					inner: Type::Float4,
198				})
199			} else if TypeId::of::<T>() == TypeId::of::<f64>() {
200				let f_val = unsafe { transmute_copy::<T, f64>(&value) };
201				OrderedF64::try_from(f_val).map(Value::Float8).unwrap_or(Value::None {
202					inner: Type::Float8,
203				})
204			} else if TypeId::of::<T>() == TypeId::of::<i8>() {
205				let i_val = unsafe { transmute_copy::<T, i8>(&value) };
206				Int1(i_val)
207			} else if TypeId::of::<T>() == TypeId::of::<i16>() {
208				let i_val = unsafe { transmute_copy::<T, i16>(&value) };
209				Int2(i_val)
210			} else if TypeId::of::<T>() == TypeId::of::<i32>() {
211				let i_val = unsafe { transmute_copy::<T, i32>(&value) };
212				Int4(i_val)
213			} else if TypeId::of::<T>() == TypeId::of::<i64>() {
214				let i_val = unsafe { transmute_copy::<T, i64>(&value) };
215				Int8(i_val)
216			} else if TypeId::of::<T>() == TypeId::of::<i128>() {
217				let i_val = unsafe { transmute_copy::<T, i128>(&value) };
218				Int16(i_val)
219			} else if TypeId::of::<T>() == TypeId::of::<u8>() {
220				let u_val = unsafe { transmute_copy::<T, u8>(&value) };
221				Uint1(u_val)
222			} else if TypeId::of::<T>() == TypeId::of::<u16>() {
223				let u_val = unsafe { transmute_copy::<T, u16>(&value) };
224				Uint2(u_val)
225			} else if TypeId::of::<T>() == TypeId::of::<u32>() {
226				let u_val = unsafe { transmute_copy::<T, u32>(&value) };
227				Uint4(u_val)
228			} else if TypeId::of::<T>() == TypeId::of::<u64>() {
229				let u_val = unsafe { transmute_copy::<T, u64>(&value) };
230				Uint8(u_val)
231			} else if TypeId::of::<T>() == TypeId::of::<u128>() {
232				let u_val = unsafe { transmute_copy::<T, u128>(&value) };
233				Uint16(u_val)
234			} else if TypeId::of::<T>() == TypeId::of::<Decimal>() {
235				let d_val = unsafe { transmute_copy::<T, Decimal>(&value) };
236				forget(value);
237				Value::Decimal(d_val)
238			} else if TypeId::of::<T>() == TypeId::of::<Int>() {
239				let i_val = unsafe { transmute_copy::<T, Int>(&value) };
240				forget(value);
241				Value::Int(i_val)
242			} else if TypeId::of::<T>() == TypeId::of::<Uint>() {
243				let u_val = unsafe { transmute_copy::<T, Uint>(&value) };
244				forget(value);
245				Value::Uint(u_val)
246			} else {
247				Value::none()
248			}
249		} else {
250			Value::none()
251		}
252	}
253
254	pub fn extend(&mut self, other: &Self) -> Result<()> {
255		DataVec::extend_iter(&mut self.data, other.data.iter().cloned());
256		Ok(())
257	}
258
259	pub fn iter(&self) -> impl Iterator<Item = Option<T>> + '_
260	where
261		T: Copy,
262	{
263		self.data.iter().map(|&v| Some(v))
264	}
265
266	pub fn slice(&self, start: usize, end: usize) -> Self {
267		let count = (end - start).min(self.len().saturating_sub(start));
268		let mut new_data = DataVec::spawn(&self.data, count);
269		for i in start..(start + count) {
270			DataVec::push(&mut new_data, self.data[i].clone());
271		}
272		Self {
273			data: new_data,
274		}
275	}
276
277	pub fn filter(&mut self, mask: &S::BitVec) {
278		let mut new_data = DataVec::spawn(&self.data, DataBitVec::count_ones(mask));
279
280		for (i, keep) in DataBitVec::iter(mask).enumerate() {
281			if keep && i < self.len() {
282				DataVec::push(&mut new_data, self.data[i].clone());
283			}
284		}
285
286		self.data = new_data;
287	}
288
289	pub fn reorder(&mut self, indices: &[usize]) {
290		let mut new_data = DataVec::spawn(&self.data, indices.len());
291
292		for &idx in indices {
293			if idx < self.len() {
294				DataVec::push(&mut new_data, self.data[idx].clone());
295			} else {
296				DataVec::push(&mut new_data, T::default());
297			}
298		}
299
300		self.data = new_data;
301	}
302
303	pub fn push_with_convert<U>(&mut self, value: U, converter: impl FnOnce(U) -> Option<T>) {
304		match converter(value) {
305			Some(v) => {
306				DataVec::push(&mut self.data, v);
307			}
308			None => {
309				DataVec::push(&mut self.data, T::default());
310			}
311		}
312	}
313
314	pub fn take(&self, num: usize) -> Self {
315		Self {
316			data: DataVec::take(&self.data, num),
317		}
318	}
319}
320
321#[cfg(test)]
322pub mod tests {
323	use super::*;
324	use crate::util::bitvec::BitVec;
325
326	#[test]
327	fn test_new_i32() {
328		let data = vec![1, 2, 3];
329		let container = NumberContainer::new(data.clone());
330
331		assert_eq!(container.len(), 3);
332		assert_eq!(container.get(0), Some(&1));
333		assert_eq!(container.get(1), Some(&2));
334		assert_eq!(container.get(2), Some(&3));
335	}
336
337	#[test]
338	fn test_from_vec_f64() {
339		let data = vec![1.1, 2.2, 3.3];
340		let container = NumberContainer::from_vec(data);
341
342		assert_eq!(container.len(), 3);
343		assert_eq!(container.get(0), Some(&1.1));
344		assert_eq!(container.get(1), Some(&2.2));
345		assert_eq!(container.get(2), Some(&3.3));
346
347		// All should be defined
348		for i in 0..3 {
349			assert!(container.is_defined(i));
350		}
351	}
352
353	#[test]
354	fn test_with_capacity() {
355		let container: NumberContainer<i32> = NumberContainer::with_capacity(10);
356		assert_eq!(container.len(), 0);
357		assert!(container.is_empty());
358		assert!(container.capacity() >= 10);
359	}
360
361	#[test]
362	fn test_push_i64() {
363		let mut container: NumberContainer<i64> = NumberContainer::with_capacity(3);
364
365		container.push(100);
366		container.push(-200);
367		container.push_default();
368
369		assert_eq!(container.len(), 3);
370		assert_eq!(container.get(0), Some(&100));
371		assert_eq!(container.get(1), Some(&-200));
372		assert_eq!(container.get(2), Some(&0)); // push_default pushes default
373
374		assert!(container.is_defined(0));
375		assert!(container.is_defined(1));
376		assert!(container.is_defined(2));
377	}
378
379	#[test]
380	fn test_extend() {
381		let mut container1 = NumberContainer::from_vec(vec![1i32, 2]);
382		let container2 = NumberContainer::from_vec(vec![3i32, 4]);
383
384		container1.extend(&container2).unwrap();
385
386		assert_eq!(container1.len(), 4);
387		assert_eq!(container1.get(0), Some(&1));
388		assert_eq!(container1.get(1), Some(&2));
389		assert_eq!(container1.get(2), Some(&3));
390		assert_eq!(container1.get(3), Some(&4));
391	}
392
393	#[test]
394	fn test_iter_u8() {
395		let data = vec![1u8, 2, 3];
396		let container = NumberContainer::new(data);
397
398		let collected: Vec<Option<u8>> = container.iter().collect();
399		assert_eq!(collected, vec![Some(1), Some(2), Some(3)]);
400	}
401
402	#[test]
403	fn test_slice() {
404		let container = NumberContainer::from_vec(vec![10i16, 20, 30, 40]);
405		let sliced = container.slice(1, 3);
406
407		assert_eq!(sliced.len(), 2);
408		assert_eq!(sliced.get(0), Some(&20));
409		assert_eq!(sliced.get(1), Some(&30));
410	}
411
412	#[test]
413	fn test_filter() {
414		let mut container = NumberContainer::from_vec(vec![1f32, 2.0, 3.0, 4.0]);
415		let mask = BitVec::from_slice(&[true, false, true, false]);
416
417		container.filter(&mask);
418
419		assert_eq!(container.len(), 2);
420		assert_eq!(container.get(0), Some(&1.0));
421		assert_eq!(container.get(1), Some(&3.0));
422	}
423
424	#[test]
425	fn test_reorder() {
426		let mut container = NumberContainer::from_vec(vec![10i32, 20, 30]);
427		let indices = [2, 0, 1];
428
429		container.reorder(&indices);
430
431		assert_eq!(container.len(), 3);
432		assert_eq!(container.get(0), Some(&30)); // was index 2
433		assert_eq!(container.get(1), Some(&10)); // was index 0
434		assert_eq!(container.get(2), Some(&20)); // was index 1
435	}
436
437	#[test]
438	fn test_push_with_convert() {
439		let mut container: NumberContainer<i32> = NumberContainer::with_capacity(3);
440
441		// Successful conversion
442		container.push_with_convert(42u32, |x| {
443			if x <= i32::MAX as u32 {
444				Some(x as i32)
445			} else {
446				None
447			}
448		});
449
450		// Failed conversion
451		container.push_with_convert(u32::MAX, |x| {
452			if x <= i32::MAX as u32 {
453				Some(x as i32)
454			} else {
455				None
456			}
457		});
458
459		assert_eq!(container.len(), 2);
460		assert_eq!(container.get(0), Some(&42));
461		assert_eq!(container.get(1), Some(&0)); // conversion failed, pushed default
462
463		assert!(container.is_defined(0));
464		assert!(container.is_defined(1));
465	}
466
467	#[test]
468	fn test_data_access() {
469		let mut container = NumberContainer::from_vec(vec![1i32, 2, 3]);
470
471		// Test immutable access
472		assert_eq!(container.data().len(), 3);
473
474		// Test mutable access
475		container.data_mut().push(4);
476
477		assert_eq!(container.len(), 4);
478		assert_eq!(container.get(3), Some(&4));
479	}
480}