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