1use std::ptr;
5
6use reifydb_value::{
7 reifydb_assertions,
8 value::{uuid::Uuid4, value_type::ValueType},
9};
10use uuid::Uuid;
11
12use crate::encoded::{row::EncodedRow, shape::RowShape};
13
14impl RowShape {
15 pub fn set_uuid4(&self, row: &mut EncodedRow, index: usize, value: Uuid4) {
16 let field = &self.fields()[index];
17 reifydb_assertions! {
18 assert!(
19 row.len() >= self.total_static_size(),
20 "row/shape size mismatch: row.len()={} < total_static_size()={}",
21 row.len(),
22 self.total_static_size()
23 );
24 assert_eq!(*field.constraint.get_type().inner_type(), ValueType::Uuid4);
25 }
26 row.set_valid(index, true);
27 unsafe {
28 ptr::write_unaligned(
29 row.make_mut().as_mut_ptr().add(field.offset as usize) as *mut [u8; 16],
30 *value.as_bytes(),
31 );
32 }
33 }
34
35 pub fn get_uuid4(&self, row: &EncodedRow, index: usize) -> Uuid4 {
36 let field = &self.fields()[index];
37 reifydb_assertions! {
38 assert!(
39 row.len() >= self.total_static_size(),
40 "row/shape size mismatch: row.len()={} < total_static_size()={}",
41 row.len(),
42 self.total_static_size()
43 );
44 assert_eq!(*field.constraint.get_type().inner_type(), ValueType::Uuid4);
45 }
46 unsafe {
47 let bytes: [u8; 16] =
48 ptr::read_unaligned(row.as_ptr().add(field.offset as usize) as *const [u8; 16]);
49 Uuid4::from(Uuid::from_bytes(bytes))
50 }
51 }
52
53 pub fn try_get_uuid4(&self, row: &EncodedRow, index: usize) -> Option<Uuid4> {
54 if row.is_defined(index) && self.fields()[index].constraint.get_type() == ValueType::Uuid4 {
55 Some(self.get_uuid4(row, index))
56 } else {
57 None
58 }
59 }
60}
61
62#[cfg(test)]
63pub mod tests {
64 use reifydb_value::value::{uuid::Uuid4, value_type::ValueType};
65
66 use crate::encoded::shape::RowShape;
67
68 #[test]
69 fn test_set_get_uuid4() {
70 let shape = RowShape::testing(&[ValueType::Uuid4]);
71 let mut row = shape.allocate();
72
73 let uuid = Uuid4::generate();
74 shape.set_uuid4(&mut row, 0, uuid.clone());
75 assert_eq!(shape.get_uuid4(&row, 0), uuid);
76 }
77
78 #[test]
79 fn test_try_get_uuid4() {
80 let shape = RowShape::testing(&[ValueType::Uuid4]);
81 let mut row = shape.allocate();
82
83 assert_eq!(shape.try_get_uuid4(&row, 0), None);
84
85 let uuid = Uuid4::generate();
86 shape.set_uuid4(&mut row, 0, uuid.clone());
87 assert_eq!(shape.try_get_uuid4(&row, 0), Some(uuid));
88 }
89
90 #[test]
91 fn test_multiple_generations() {
92 let shape = RowShape::testing(&[ValueType::Uuid4]);
93
94 let mut uuids = Vec::new();
96 for _ in 0..10 {
97 let mut row = shape.allocate();
98 let uuid = Uuid4::generate();
99 shape.set_uuid4(&mut row, 0, uuid.clone());
100 let retrieved = shape.get_uuid4(&row, 0);
101 assert_eq!(retrieved, uuid);
102 uuids.push(uuid);
103 }
104
105 for i in 0..uuids.len() {
107 for j in (i + 1)..uuids.len() {
108 assert_ne!(uuids[i], uuids[j], "UUIDs should be unique");
109 }
110 }
111 }
112
113 #[test]
114 fn test_version_check() {
115 let shape = RowShape::testing(&[ValueType::Uuid4]);
116 let mut row = shape.allocate();
117
118 let uuid = Uuid4::generate();
119 shape.set_uuid4(&mut row, 0, uuid.clone());
120 let retrieved = shape.get_uuid4(&row, 0);
121
122 assert_eq!(retrieved.get_version_num(), 4);
124 }
125
126 #[test]
127 fn test_mixed_with_other_types() {
128 let shape =
129 RowShape::testing(&[ValueType::Uuid4, ValueType::Boolean, ValueType::Uuid4, ValueType::Int4]);
130 let mut row = shape.allocate();
131
132 let uuid1 = Uuid4::generate();
133 let uuid2 = Uuid4::generate();
134
135 shape.set_uuid4(&mut row, 0, uuid1.clone());
136 shape.set_bool(&mut row, 1, true);
137 shape.set_uuid4(&mut row, 2, uuid2.clone());
138 shape.set_i32(&mut row, 3, 42);
139
140 assert_eq!(shape.get_uuid4(&row, 0), uuid1);
141 assert_eq!(shape.get_bool(&row, 1), true);
142 assert_eq!(shape.get_uuid4(&row, 2), uuid2);
143 assert_eq!(shape.get_i32(&row, 3), 42);
144 }
145
146 #[test]
147 fn test_undefined_handling() {
148 let shape = RowShape::testing(&[ValueType::Uuid4, ValueType::Uuid4]);
149 let mut row = shape.allocate();
150
151 let uuid = Uuid4::generate();
152 shape.set_uuid4(&mut row, 0, uuid.clone());
153
154 assert_eq!(shape.try_get_uuid4(&row, 0), Some(uuid));
155 assert_eq!(shape.try_get_uuid4(&row, 1), None);
156
157 shape.set_none(&mut row, 0);
158 assert_eq!(shape.try_get_uuid4(&row, 0), None);
159 }
160
161 #[test]
162 fn test_persistence() {
163 let shape = RowShape::testing(&[ValueType::Uuid4]);
164 let mut row = shape.allocate();
165
166 let uuid = Uuid4::generate();
167 let uuid_string = uuid.to_string();
168
169 shape.set_uuid4(&mut row, 0, uuid.clone());
170 let retrieved = shape.get_uuid4(&row, 0);
171
172 assert_eq!(retrieved, uuid);
173 assert_eq!(retrieved.to_string(), uuid_string);
174 assert_eq!(retrieved.as_bytes(), uuid.as_bytes());
175 }
176
177 #[test]
178 fn test_clone_consistency() {
179 let shape = RowShape::testing(&[ValueType::Uuid4]);
180 let mut row = shape.allocate();
181
182 let original_uuid = Uuid4::generate();
183 shape.set_uuid4(&mut row, 0, original_uuid.clone());
184
185 let retrieved_uuid = shape.get_uuid4(&row, 0);
186 assert_eq!(retrieved_uuid, original_uuid);
187
188 assert_eq!(retrieved_uuid.as_bytes(), original_uuid.as_bytes());
190 }
191
192 #[test]
193 fn test_multiple_fields() {
194 let shape = RowShape::testing(&[ValueType::Uuid4, ValueType::Uuid4, ValueType::Uuid4]);
195 let mut row = shape.allocate();
196
197 let uuid1 = Uuid4::generate();
198 let uuid2 = Uuid4::generate();
199 let uuid3 = Uuid4::generate();
200
201 shape.set_uuid4(&mut row, 0, uuid1.clone());
202 shape.set_uuid4(&mut row, 1, uuid2.clone());
203 shape.set_uuid4(&mut row, 2, uuid3.clone());
204
205 assert_eq!(shape.get_uuid4(&row, 0), uuid1);
206 assert_eq!(shape.get_uuid4(&row, 1), uuid2);
207 assert_eq!(shape.get_uuid4(&row, 2), uuid3);
208
209 assert_ne!(uuid1, uuid2);
211 assert_ne!(uuid1, uuid3);
212 assert_ne!(uuid2, uuid3);
213 }
214
215 #[test]
216 fn test_format_consistency() {
217 let shape = RowShape::testing(&[ValueType::Uuid4]);
218 let mut row = shape.allocate();
219
220 let uuid = Uuid4::generate();
221 let original_string = uuid.to_string();
222
223 shape.set_uuid4(&mut row, 0, uuid.clone());
224 let retrieved = shape.get_uuid4(&row, 0);
225 let retrieved_string = retrieved.to_string();
226
227 assert_eq!(original_string, retrieved_string);
228
229 assert_eq!(original_string.len(), 36);
231 assert_eq!(original_string.matches('-').count(), 4);
232 }
233
234 #[test]
235 fn test_byte_level_storage() {
236 let shape = RowShape::testing(&[ValueType::Uuid4]);
237 let mut row = shape.allocate();
238
239 let uuid = Uuid4::generate();
240 let original_bytes = *uuid.as_bytes();
241
242 shape.set_uuid4(&mut row, 0, uuid.clone());
243 let retrieved = shape.get_uuid4(&row, 0);
244 let retrieved_bytes = *retrieved.as_bytes();
245
246 assert_eq!(original_bytes, retrieved_bytes);
247
248 assert_eq!(original_bytes.len(), 16);
250 assert_eq!(retrieved_bytes.len(), 16);
251 }
252
253 #[test]
254 fn test_try_get_uuid4_wrong_type() {
255 let shape = RowShape::testing(&[ValueType::Boolean]);
256 let mut row = shape.allocate();
257
258 shape.set_bool(&mut row, 0, true);
259
260 assert_eq!(shape.try_get_uuid4(&row, 0), None);
261 }
262}