Skip to main content

reifydb_type/value/container/
uuid.rs

1// SPDX-License-Identifier: MIT
2// Copyright (c) 2025 ReifyDB
3
4use std::{
5	any::TypeId,
6	fmt::{self, Debug},
7	mem::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		is::IsUuid,
21		uuid::{Uuid4, Uuid7},
22	},
23};
24
25pub struct UuidContainer<T, S: Storage = Cow>
26where
27	T: IsUuid,
28{
29	data: S::Vec<T>,
30}
31
32impl<T: IsUuid, S: Storage> Clone for UuidContainer<T, S> {
33	fn clone(&self) -> Self {
34		Self {
35			data: self.data.clone(),
36		}
37	}
38}
39
40impl<T: IsUuid + Debug, S: Storage> Debug for UuidContainer<T, S>
41where
42	S::Vec<T>: Debug,
43{
44	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45		f.debug_struct("UuidContainer").field("data", &self.data).finish()
46	}
47}
48
49impl<T: IsUuid, S: Storage> PartialEq for UuidContainer<T, S>
50where
51	S::Vec<T>: PartialEq,
52{
53	fn eq(&self, other: &Self) -> bool {
54		self.data == other.data
55	}
56}
57
58impl<T: IsUuid + Serialize> Serialize for UuidContainer<T, Cow> {
59	fn serialize<Ser: Serializer>(&self, serializer: Ser) -> StdResult<Ser::Ok, Ser::Error> {
60		#[derive(Serialize)]
61		struct Helper<'a, T: Clone + PartialEq + Serialize> {
62			data: &'a CowVec<T>,
63		}
64		Helper {
65			data: &self.data,
66		}
67		.serialize(serializer)
68	}
69}
70
71impl<'de, T: IsUuid + Deserialize<'de>> Deserialize<'de> for UuidContainer<T, Cow> {
72	fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
73		#[derive(Deserialize)]
74		struct Helper<T: Clone + PartialEq> {
75			data: CowVec<T>,
76		}
77		let h = Helper::deserialize(deserializer)?;
78		Ok(UuidContainer {
79			data: h.data,
80		})
81	}
82}
83
84impl<T: IsUuid, S: Storage> Deref for UuidContainer<T, S> {
85	type Target = [T];
86
87	fn deref(&self) -> &Self::Target {
88		self.data.as_slice()
89	}
90}
91
92impl<T> UuidContainer<T, Cow>
93where
94	T: IsUuid + Clone + Debug + Default,
95{
96	pub fn new(data: Vec<T>) -> Self {
97		Self {
98			data: CowVec::new(data),
99		}
100	}
101
102	pub fn with_capacity(capacity: usize) -> Self {
103		Self {
104			data: CowVec::with_capacity(capacity),
105		}
106	}
107
108	pub fn from_vec(data: Vec<T>) -> Self {
109		Self {
110			data: CowVec::new(data),
111		}
112	}
113}
114
115impl<T, S: Storage> UuidContainer<T, S>
116where
117	T: IsUuid + Clone + Debug + Default,
118{
119	pub fn from_parts(data: S::Vec<T>) -> Self {
120		Self {
121			data,
122		}
123	}
124
125	pub fn len(&self) -> usize {
126		DataVec::len(&self.data)
127	}
128
129	pub fn capacity(&self) -> usize {
130		DataVec::capacity(&self.data)
131	}
132
133	pub fn is_empty(&self) -> bool {
134		DataVec::is_empty(&self.data)
135	}
136
137	pub fn clear(&mut self) {
138		DataVec::clear(&mut self.data);
139	}
140
141	pub fn push(&mut self, value: T) {
142		DataVec::push(&mut self.data, value);
143	}
144
145	pub fn push_default(&mut self) {
146		DataVec::push(&mut self.data, T::default());
147	}
148
149	pub fn get(&self, index: usize) -> Option<&T> {
150		if index < self.len() {
151			DataVec::get(&self.data, index)
152		} else {
153			None
154		}
155	}
156
157	pub fn is_defined(&self, idx: usize) -> bool {
158		idx < self.len()
159	}
160
161	pub fn data(&self) -> &S::Vec<T> {
162		&self.data
163	}
164
165	pub fn data_mut(&mut self) -> &mut S::Vec<T> {
166		&mut self.data
167	}
168
169	pub fn as_string(&self, index: usize) -> String {
170		if index < self.len() {
171			self.data[index].to_string()
172		} else {
173			"none".to_string()
174		}
175	}
176
177	pub fn get_value(&self, index: usize) -> Value
178	where
179		T: 'static,
180	{
181		if index < self.len() {
182			let value = self.data[index].clone();
183
184			if TypeId::of::<T>() == TypeId::of::<Uuid4>() {
185				let uuid_val = unsafe { transmute_copy::<T, Uuid4>(&value) };
186				Value::Uuid4(uuid_val)
187			} else if TypeId::of::<T>() == TypeId::of::<Uuid7>() {
188				let uuid_val = unsafe { transmute_copy::<T, Uuid7>(&value) };
189				Value::Uuid7(uuid_val)
190			} else {
191				Value::none()
192			}
193		} else {
194			Value::none()
195		}
196	}
197
198	pub fn extend(&mut self, other: &Self) -> Result<()> {
199		DataVec::extend_iter(&mut self.data, other.data.iter().cloned());
200		Ok(())
201	}
202
203	pub fn iter(&self) -> impl Iterator<Item = Option<T>> + '_
204	where
205		T: Copy,
206	{
207		self.data.iter().map(|&v| Some(v))
208	}
209
210	pub fn slice(&self, start: usize, end: usize) -> Self {
211		let count = (end - start).min(self.len().saturating_sub(start));
212		let mut new_data = DataVec::spawn(&self.data, count);
213		for i in start..(start + count) {
214			DataVec::push(&mut new_data, self.data[i].clone());
215		}
216		Self {
217			data: new_data,
218		}
219	}
220
221	pub fn filter(&mut self, mask: &S::BitVec) {
222		let mut new_data = DataVec::spawn(&self.data, DataBitVec::count_ones(mask));
223
224		for (i, keep) in DataBitVec::iter(mask).enumerate() {
225			if keep && i < self.len() {
226				DataVec::push(&mut new_data, self.data[i].clone());
227			}
228		}
229
230		self.data = new_data;
231	}
232
233	pub fn reorder(&mut self, indices: &[usize]) {
234		let mut new_data = DataVec::spawn(&self.data, indices.len());
235
236		for &idx in indices {
237			if idx < self.len() {
238				DataVec::push(&mut new_data, self.data[idx].clone());
239			} else {
240				DataVec::push(&mut new_data, T::default());
241			}
242		}
243
244		self.data = new_data;
245	}
246
247	pub fn take(&self, num: usize) -> Self {
248		Self {
249			data: DataVec::take(&self.data, num),
250		}
251	}
252}
253
254impl<T> Default for UuidContainer<T, Cow>
255where
256	T: IsUuid + Clone + Debug + Default,
257{
258	fn default() -> Self {
259		Self::with_capacity(0)
260	}
261}
262
263#[cfg(test)]
264pub mod tests {
265	use super::*;
266
267	#[test]
268	fn test_uuid4_container() {
269		let uuid1 = Uuid4::generate();
270		let uuid2 = Uuid4::generate();
271		let uuids = vec![uuid1, uuid2];
272		let container = UuidContainer::from_vec(uuids.clone());
273
274		assert_eq!(container.len(), 2);
275		assert_eq!(container.get(0), Some(&uuids[0]));
276		assert_eq!(container.get(1), Some(&uuids[1]));
277
278		for i in 0..2 {
279			assert!(container.is_defined(i));
280		}
281	}
282
283	#[test]
284	fn test_uuid7_container() {
285		let uuid1 = Uuid7::generate();
286		let uuid2 = Uuid7::generate();
287		let uuids = vec![uuid1, uuid2];
288		let container = UuidContainer::from_vec(uuids.clone());
289
290		assert_eq!(container.len(), 2);
291		assert_eq!(container.get(0), Some(&uuids[0]));
292		assert_eq!(container.get(1), Some(&uuids[1]));
293	}
294
295	#[test]
296	fn test_with_capacity() {
297		let container: UuidContainer<Uuid4> = UuidContainer::with_capacity(10);
298		assert_eq!(container.len(), 0);
299		assert!(container.is_empty());
300		assert!(container.capacity() >= 10);
301	}
302
303	#[test]
304	fn test_push_with_default() {
305		let mut container: UuidContainer<Uuid4> = UuidContainer::with_capacity(3);
306		let uuid1 = Uuid4::generate();
307		let uuid2 = Uuid4::generate();
308
309		container.push(uuid1);
310		container.push_default();
311		container.push(uuid2);
312
313		assert_eq!(container.len(), 3);
314		assert_eq!(container.get(0), Some(&uuid1));
315		assert_eq!(container.get(1), Some(&Uuid4::default())); // default
316		assert_eq!(container.get(2), Some(&uuid2));
317
318		assert!(container.is_defined(0));
319		assert!(container.is_defined(1));
320		assert!(container.is_defined(2));
321	}
322
323	#[test]
324	fn test_default() {
325		let container: UuidContainer<Uuid4> = UuidContainer::default();
326		assert_eq!(container.len(), 0);
327		assert!(container.is_empty());
328	}
329}