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