1use crate::context::ReadContext;
19use crate::context::WriteContext;
20use crate::error::Error;
21use crate::resolver::TypeResolver;
22use crate::serializer::util::read_basic_type_info;
23use crate::serializer::ForyDefault;
24use crate::serializer::Serializer;
25use crate::type_id::TypeId;
26use crate::types::{Date, Duration, Timestamp};
27use std::mem;
28
29impl Serializer for Timestamp {
30 #[inline(always)]
31 fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
32 context.writer.write_i64(self.seconds());
33 context.writer.write_u32(self.subsec_nanos());
34 Ok(())
35 }
36
37 #[inline(always)]
38 fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error> {
39 let seconds = context.reader.read_i64()?;
40 let nanos = context.reader.read_u32()?;
41 Timestamp::new(seconds, nanos)
42 }
43 #[inline]
44 fn fory_read_data_as_send_sync_any(
45 context: &mut ReadContext,
46 ) -> Result<Box<dyn std::any::Any + Send + Sync>, Error>
47 where
48 Self: Sized + ForyDefault,
49 {
50 Ok(crate::serializer::box_send_sync(Self::fory_read_data(
51 context,
52 )?))
53 }
54
55 #[inline(always)]
56 fn fory_reserved_space() -> usize {
57 mem::size_of::<i64>() + mem::size_of::<u32>()
58 }
59
60 #[inline(always)]
61 fn fory_get_type_id(_: &TypeResolver) -> Result<TypeId, Error> {
62 Ok(TypeId::TIMESTAMP)
63 }
64
65 #[inline(always)]
66 fn fory_type_id_dyn(&self, _: &TypeResolver) -> Result<TypeId, Error> {
67 Ok(TypeId::TIMESTAMP)
68 }
69
70 #[inline(always)]
71 fn fory_static_type_id() -> TypeId {
72 TypeId::TIMESTAMP
73 }
74
75 #[inline(always)]
76 fn as_any(&self) -> &dyn std::any::Any {
77 self
78 }
79
80 #[inline(always)]
81 fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error> {
82 context.writer.write_u8(TypeId::TIMESTAMP as u8);
83 Ok(())
84 }
85
86 #[inline(always)]
87 fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
88 read_basic_type_info::<Self>(context)
89 }
90}
91
92impl ForyDefault for Timestamp {
93 #[inline(always)]
94 fn fory_default() -> Self {
95 Timestamp::default()
96 }
97}
98
99impl Serializer for Date {
100 #[inline(always)]
101 fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
102 let days = self.epoch_days();
103 if context.is_xlang() {
104 context.writer.write_var_i64(days);
105 } else {
106 let native_days = i32::try_from(days).map_err(|_| {
107 Error::invalid_data(format!("date day count {} exceeds native i32 range", days))
108 })?;
109 context.writer.write_i32(native_days);
110 }
111 Ok(())
112 }
113
114 #[inline(always)]
115 fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error> {
116 let days = if context.is_xlang() {
117 context.reader.read_var_i64()?
118 } else {
119 i64::from(context.reader.read_i32()?)
120 };
121 Ok(Date::from_epoch_days(days))
122 }
123 #[inline]
124 fn fory_read_data_as_send_sync_any(
125 context: &mut ReadContext,
126 ) -> Result<Box<dyn std::any::Any + Send + Sync>, Error>
127 where
128 Self: Sized + ForyDefault,
129 {
130 Ok(crate::serializer::box_send_sync(Self::fory_read_data(
131 context,
132 )?))
133 }
134
135 #[inline(always)]
136 fn fory_reserved_space() -> usize {
137 9
138 }
139
140 #[inline(always)]
141 fn fory_get_type_id(_: &TypeResolver) -> Result<TypeId, Error> {
142 Ok(TypeId::DATE)
143 }
144
145 #[inline(always)]
146 fn fory_type_id_dyn(&self, _: &TypeResolver) -> Result<TypeId, Error> {
147 Ok(TypeId::DATE)
148 }
149
150 #[inline(always)]
151 fn fory_static_type_id() -> TypeId {
152 TypeId::DATE
153 }
154
155 #[inline(always)]
156 fn as_any(&self) -> &dyn std::any::Any {
157 self
158 }
159
160 #[inline(always)]
161 fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error> {
162 context.writer.write_u8(TypeId::DATE as u8);
163 Ok(())
164 }
165
166 #[inline(always)]
167 fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
168 read_basic_type_info::<Self>(context)
169 }
170}
171
172impl ForyDefault for Date {
173 #[inline(always)]
174 fn fory_default() -> Self {
175 Date::default()
176 }
177}
178
179impl Serializer for Duration {
180 #[inline(always)]
181 fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
182 context.writer.write_var_i64(self.seconds());
183 context.writer.write_i32(self.subsec_nanos() as i32);
184 Ok(())
185 }
186
187 #[inline(always)]
188 fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error> {
189 let seconds = context.reader.read_var_i64()?;
190 let nanos = context.reader.read_i32()?;
191 Duration::new(seconds, nanos)
192 }
193 #[inline]
194 fn fory_read_data_as_send_sync_any(
195 context: &mut ReadContext,
196 ) -> Result<Box<dyn std::any::Any + Send + Sync>, Error>
197 where
198 Self: Sized + ForyDefault,
199 {
200 Ok(crate::serializer::box_send_sync(Self::fory_read_data(
201 context,
202 )?))
203 }
204
205 #[inline(always)]
206 fn fory_reserved_space() -> usize {
207 9 + mem::size_of::<i32>()
208 }
209
210 #[inline(always)]
211 fn fory_get_type_id(_: &TypeResolver) -> Result<TypeId, Error> {
212 Ok(TypeId::DURATION)
213 }
214
215 #[inline(always)]
216 fn fory_type_id_dyn(&self, _: &TypeResolver) -> Result<TypeId, Error> {
217 Ok(TypeId::DURATION)
218 }
219
220 #[inline(always)]
221 fn fory_static_type_id() -> TypeId {
222 TypeId::DURATION
223 }
224
225 #[inline(always)]
226 fn as_any(&self) -> &dyn std::any::Any {
227 self
228 }
229
230 #[inline(always)]
231 fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error> {
232 context.writer.write_u8(TypeId::DURATION as u8);
233 Ok(())
234 }
235
236 #[inline(always)]
237 fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
238 read_basic_type_info::<Self>(context)
239 }
240}
241
242impl ForyDefault for Duration {
243 #[inline(always)]
244 fn fory_default() -> Self {
245 Duration::default()
246 }
247}
248
249#[cfg(feature = "chrono")]
250mod chrono_support {
251 use super::*;
252 use chrono::{Duration as ChronoDuration, NaiveDate, NaiveDateTime};
253
254 impl Serializer for NaiveDateTime {
255 #[inline(always)]
256 fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
257 Timestamp::from(*self).fory_write_data(context)
258 }
259
260 #[inline(always)]
261 fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error> {
262 Timestamp::fory_read_data(context)?.try_into()
263 }
264 #[inline]
265 fn fory_read_data_as_send_sync_any(
266 context: &mut ReadContext,
267 ) -> Result<Box<dyn std::any::Any + Send + Sync>, Error>
268 where
269 Self: Sized + ForyDefault,
270 {
271 Ok(crate::serializer::box_send_sync(Self::fory_read_data(
272 context,
273 )?))
274 }
275
276 #[inline(always)]
277 fn fory_reserved_space() -> usize {
278 Timestamp::fory_reserved_space()
279 }
280
281 #[inline(always)]
282 fn fory_get_type_id(_: &TypeResolver) -> Result<TypeId, Error> {
283 Ok(TypeId::TIMESTAMP)
284 }
285
286 #[inline(always)]
287 fn fory_type_id_dyn(&self, _: &TypeResolver) -> Result<TypeId, Error> {
288 Ok(TypeId::TIMESTAMP)
289 }
290
291 #[inline(always)]
292 fn fory_static_type_id() -> TypeId {
293 TypeId::TIMESTAMP
294 }
295
296 #[inline(always)]
297 fn as_any(&self) -> &dyn std::any::Any {
298 self
299 }
300
301 #[inline(always)]
302 fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error> {
303 Timestamp::fory_write_type_info(context)
304 }
305
306 #[inline(always)]
307 fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
308 read_basic_type_info::<Self>(context)
309 }
310 }
311
312 impl ForyDefault for NaiveDateTime {
313 #[inline(always)]
314 fn fory_default() -> Self {
315 NaiveDateTime::default()
316 }
317 }
318
319 impl Serializer for NaiveDate {
320 #[inline(always)]
321 fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
322 Date::from(*self).fory_write_data(context)
323 }
324
325 #[inline(always)]
326 fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error> {
327 Date::fory_read_data(context)?.try_into()
328 }
329 #[inline]
330 fn fory_read_data_as_send_sync_any(
331 context: &mut ReadContext,
332 ) -> Result<Box<dyn std::any::Any + Send + Sync>, Error>
333 where
334 Self: Sized + ForyDefault,
335 {
336 Ok(crate::serializer::box_send_sync(Self::fory_read_data(
337 context,
338 )?))
339 }
340
341 #[inline(always)]
342 fn fory_reserved_space() -> usize {
343 Date::fory_reserved_space()
344 }
345
346 #[inline(always)]
347 fn fory_get_type_id(_: &TypeResolver) -> Result<TypeId, Error> {
348 Ok(TypeId::DATE)
349 }
350
351 #[inline(always)]
352 fn fory_type_id_dyn(&self, _: &TypeResolver) -> Result<TypeId, Error> {
353 Ok(TypeId::DATE)
354 }
355
356 #[inline(always)]
357 fn fory_static_type_id() -> TypeId {
358 TypeId::DATE
359 }
360
361 #[inline(always)]
362 fn as_any(&self) -> &dyn std::any::Any {
363 self
364 }
365
366 #[inline(always)]
367 fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error> {
368 Date::fory_write_type_info(context)
369 }
370
371 #[inline(always)]
372 fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
373 read_basic_type_info::<Self>(context)
374 }
375 }
376
377 impl ForyDefault for NaiveDate {
378 #[inline(always)]
379 fn fory_default() -> Self {
380 NaiveDate::default()
381 }
382 }
383
384 impl Serializer for ChronoDuration {
385 #[inline(always)]
386 fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
387 Duration::try_from(*self)?.fory_write_data(context)
388 }
389
390 #[inline(always)]
391 fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error> {
392 Duration::fory_read_data(context)?.try_into()
393 }
394 #[inline]
395 fn fory_read_data_as_send_sync_any(
396 context: &mut ReadContext,
397 ) -> Result<Box<dyn std::any::Any + Send + Sync>, Error>
398 where
399 Self: Sized + ForyDefault,
400 {
401 Ok(crate::serializer::box_send_sync(Self::fory_read_data(
402 context,
403 )?))
404 }
405
406 #[inline(always)]
407 fn fory_reserved_space() -> usize {
408 Duration::fory_reserved_space()
409 }
410
411 #[inline(always)]
412 fn fory_get_type_id(_: &TypeResolver) -> Result<TypeId, Error> {
413 Ok(TypeId::DURATION)
414 }
415
416 #[inline(always)]
417 fn fory_type_id_dyn(&self, _: &TypeResolver) -> Result<TypeId, Error> {
418 Ok(TypeId::DURATION)
419 }
420
421 #[inline(always)]
422 fn fory_static_type_id() -> TypeId {
423 TypeId::DURATION
424 }
425
426 #[inline(always)]
427 fn as_any(&self) -> &dyn std::any::Any {
428 self
429 }
430
431 #[inline(always)]
432 fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error> {
433 Duration::fory_write_type_info(context)
434 }
435
436 #[inline(always)]
437 fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
438 read_basic_type_info::<Self>(context)
439 }
440 }
441
442 impl ForyDefault for ChronoDuration {
443 #[inline(always)]
444 fn fory_default() -> Self {
445 ChronoDuration::zero()
446 }
447 }
448}
449
450#[cfg(test)]
451mod tests {
452 use super::*;
453 use crate::fory::Fory;
454
455 #[test]
456 fn test_temporal_carrier_serialization() {
457 let fory = Fory::builder().xlang(false).compatible(false).build();
458
459 let timestamps = [
460 Timestamp::UNIX_EPOCH,
461 Timestamp::new(1, 0).unwrap(),
462 Timestamp::new(-1, 999_999_999).unwrap(),
463 ];
464 for timestamp in timestamps {
465 let bytes = fory.serialize(×tamp).unwrap();
466 let deserialized: Timestamp = fory.deserialize(&bytes).unwrap();
467 assert_eq!(timestamp, deserialized);
468 }
469
470 let dates = [
471 Date::UNIX_EPOCH,
472 Date::from_epoch_days(-1),
473 Date::from_epoch_days(18_628),
474 ];
475 for date in dates {
476 let bytes = fory.serialize(&date).unwrap();
477 let deserialized: Date = fory.deserialize(&bytes).unwrap();
478 assert_eq!(date, deserialized);
479 }
480
481 let durations = [
482 Duration::ZERO,
483 Duration::new(1, 0).unwrap(),
484 Duration::new(0, -1).unwrap(),
485 Duration::new(-123, 456_789).unwrap(),
486 ];
487 for duration in durations {
488 let bytes = fory.serialize(&duration).unwrap();
489 let deserialized: Duration = fory.deserialize(&bytes).unwrap();
490 assert_eq!(duration, deserialized);
491 }
492 }
493
494 #[test]
495 fn test_duration_normalizes_negative_nanoseconds() {
496 assert_eq!(
497 Duration::new(0, -1).unwrap(),
498 Duration::from_normalized(-1, 999_999_999).unwrap()
499 );
500 }
501
502 #[cfg(feature = "chrono")]
503 #[test]
504 fn test_chrono_temporal_feature_serialization() {
505 use chrono::{DateTime, Duration as ChronoDuration, NaiveDate, NaiveDateTime};
506
507 let fory = Fory::builder().xlang(false).compatible(false).build();
508 let date = NaiveDate::from_ymd_opt(2024, 2, 3).unwrap();
509 let timestamp = DateTime::from_timestamp(100, 1).unwrap().naive_utc();
510 let duration = ChronoDuration::nanoseconds(-1);
511
512 let bytes = fory.serialize(&date).unwrap();
513 let deserialized: NaiveDate = fory.deserialize(&bytes).unwrap();
514 assert_eq!(date, deserialized);
515
516 let bytes = fory.serialize(×tamp).unwrap();
517 let deserialized: NaiveDateTime = fory.deserialize(&bytes).unwrap();
518 assert_eq!(timestamp, deserialized);
519
520 let bytes = fory.serialize(&duration).unwrap();
521 let deserialized: ChronoDuration = fory.deserialize(&bytes).unwrap();
522 assert_eq!(duration, deserialized);
523 }
524}