1use std::ptr;
5
6use reifydb_type::value::{time::Time, r#type::Type};
7
8use crate::encoded::{encoded::EncodedValues, schema::Schema};
9
10impl Schema {
11 pub fn set_time(&self, row: &mut EncodedValues, index: usize, value: Time) {
12 let field = &self.fields()[index];
13 debug_assert!(row.len() >= self.total_static_size());
14 debug_assert_eq!(*field.constraint.get_type().inner_type(), Type::Time);
15 row.set_valid(index, true);
16 unsafe {
17 ptr::write_unaligned(
18 row.make_mut().as_mut_ptr().add(field.offset as usize) as *mut u64,
19 value.to_nanos_since_midnight(),
20 )
21 }
22 }
23
24 pub fn get_time(&self, row: &EncodedValues, index: usize) -> Time {
25 let field = &self.fields()[index];
26 debug_assert!(row.len() >= self.total_static_size());
27 debug_assert_eq!(*field.constraint.get_type().inner_type(), Type::Time);
28 unsafe {
29 Time::from_nanos_since_midnight(
30 (row.as_ptr().add(field.offset as usize) as *const u64).read_unaligned(),
31 )
32 .unwrap()
33 }
34 }
35
36 pub fn try_get_time(&self, row: &EncodedValues, index: usize) -> Option<Time> {
37 if row.is_defined(index) && self.fields()[index].constraint.get_type() == Type::Time {
38 Some(self.get_time(row, index))
39 } else {
40 None
41 }
42 }
43}
44
45#[cfg(test)]
46pub mod tests {
47 use reifydb_type::value::{time::Time, r#type::Type};
48
49 use crate::encoded::schema::Schema;
50
51 #[test]
52 fn test_set_get_time() {
53 let schema = Schema::testing(&[Type::Time]);
54 let mut row = schema.allocate();
55
56 let value = Time::new(20, 50, 0, 0).unwrap();
57 schema.set_time(&mut row, 0, value.clone());
58 assert_eq!(schema.get_time(&row, 0), value);
59 }
60
61 #[test]
62 fn test_try_get_time() {
63 let schema = Schema::testing(&[Type::Time]);
64 let mut row = schema.allocate();
65
66 assert_eq!(schema.try_get_time(&row, 0), None);
67
68 let test_time = Time::from_hms(14, 30, 45).unwrap();
69 schema.set_time(&mut row, 0, test_time.clone());
70 assert_eq!(schema.try_get_time(&row, 0), Some(test_time));
71 }
72
73 #[test]
74 fn test_time_midnight() {
75 let schema = Schema::testing(&[Type::Time]);
76 let mut row = schema.allocate();
77
78 let midnight = Time::default(); schema.set_time(&mut row, 0, midnight.clone());
80 assert_eq!(schema.get_time(&row, 0), midnight);
81 }
82
83 #[test]
84 fn test_time_with_nanoseconds() {
85 let schema = Schema::testing(&[Type::Time]);
86 let mut row = schema.allocate();
87
88 let precise_time = Time::new(15, 30, 45, 123456789).unwrap();
90 schema.set_time(&mut row, 0, precise_time.clone());
91 assert_eq!(schema.get_time(&row, 0), precise_time);
92 }
93
94 #[test]
95 fn test_time_various_times() {
96 let schema = Schema::testing(&[Type::Time]);
97
98 let test_times = [
99 Time::new(0, 0, 0, 0).unwrap(), Time::new(12, 0, 0, 0).unwrap(), Time::new(23, 59, 59, 999999999).unwrap(), Time::new(6, 30, 15, 500000000).unwrap(), Time::new(18, 45, 30, 750000000).unwrap(), ];
105
106 for time in test_times {
107 let mut row = schema.allocate();
108 schema.set_time(&mut row, 0, time.clone());
109 assert_eq!(schema.get_time(&row, 0), time);
110 }
111 }
112
113 #[test]
114 fn test_time_boundary_cases() {
115 let schema = Schema::testing(&[Type::Time]);
116
117 let boundary_times = [
118 Time::new(0, 0, 0, 0).unwrap(), Time::new(0, 0, 0, 1).unwrap(), Time::new(23, 59, 59, 999999998).unwrap(), Time::new(23, 59, 59, 999999999).unwrap(), ];
124
125 for time in boundary_times {
126 let mut row = schema.allocate();
127 schema.set_time(&mut row, 0, time.clone());
128 assert_eq!(schema.get_time(&row, 0), time);
129 }
130 }
131
132 #[test]
133 fn test_time_mixed_with_other_types() {
134 let schema = Schema::testing(&[Type::Time, Type::Boolean, Type::Time, Type::Int4]);
135 let mut row = schema.allocate();
136
137 let time1 = Time::new(9, 15, 30, 0).unwrap();
138 let time2 = Time::new(21, 45, 0, 250000000).unwrap();
139
140 schema.set_time(&mut row, 0, time1.clone());
141 schema.set_bool(&mut row, 1, false);
142 schema.set_time(&mut row, 2, time2.clone());
143 schema.set_i32(&mut row, 3, -999);
144
145 assert_eq!(schema.get_time(&row, 0), time1);
146 assert_eq!(schema.get_bool(&row, 1), false);
147 assert_eq!(schema.get_time(&row, 2), time2);
148 assert_eq!(schema.get_i32(&row, 3), -999);
149 }
150
151 #[test]
152 fn test_time_undefined_handling() {
153 let schema = Schema::testing(&[Type::Time, Type::Time]);
154 let mut row = schema.allocate();
155
156 let time = Time::new(16, 20, 45, 333000000).unwrap();
157 schema.set_time(&mut row, 0, time.clone());
158
159 assert_eq!(schema.try_get_time(&row, 0), Some(time));
160 assert_eq!(schema.try_get_time(&row, 1), None);
161
162 schema.set_undefined(&mut row, 0);
163 assert_eq!(schema.try_get_time(&row, 0), None);
164 }
165
166 #[test]
167 fn test_time_precision_preservation() {
168 let schema = Schema::testing(&[Type::Time]);
169 let mut row = schema.allocate();
170
171 let high_precision = Time::new(12, 34, 56, 987654321).unwrap();
173 schema.set_time(&mut row, 0, high_precision.clone());
174
175 let retrieved = schema.get_time(&row, 0);
176 assert_eq!(retrieved, high_precision);
177 assert_eq!(retrieved.to_nanos_since_midnight(), high_precision.to_nanos_since_midnight());
178 }
179
180 #[test]
181 fn test_time_microsecond_precision() {
182 let schema = Schema::testing(&[Type::Time]);
183 let mut row = schema.allocate();
184
185 let microsecond_precision = Time::new(14, 25, 30, 123456000).unwrap();
187 schema.set_time(&mut row, 0, microsecond_precision.clone());
188 assert_eq!(schema.get_time(&row, 0), microsecond_precision);
189 }
190
191 #[test]
192 fn test_time_millisecond_precision() {
193 let schema = Schema::testing(&[Type::Time]);
194 let mut row = schema.allocate();
195
196 let millisecond_precision = Time::new(8, 15, 42, 123000000).unwrap();
198 schema.set_time(&mut row, 0, millisecond_precision.clone());
199 assert_eq!(schema.get_time(&row, 0), millisecond_precision);
200 }
201
202 #[test]
203 fn test_time_common_times() {
204 let schema = Schema::testing(&[Type::Time]);
205
206 let common_times = [
208 Time::new(9, 0, 0, 0).unwrap(), Time::new(12, 0, 0, 0).unwrap(), Time::new(17, 0, 0, 0).unwrap(), Time::new(0, 0, 1, 0).unwrap(), Time::new(23, 59, 0, 0).unwrap(), ];
214
215 for time in common_times {
216 let mut row = schema.allocate();
217 schema.set_time(&mut row, 0, time.clone());
218 assert_eq!(schema.get_time(&row, 0), time);
219 }
220 }
221
222 #[test]
223 fn test_try_get_time_wrong_type() {
224 let schema = Schema::testing(&[Type::Boolean]);
225 let mut row = schema.allocate();
226
227 schema.set_bool(&mut row, 0, true);
228
229 assert_eq!(schema.try_get_time(&row, 0), None);
230 }
231}