Skip to main content

fory_core/serializer/
datetime.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use crate::error::Error;
19use crate::resolver::context::ReadContext;
20use crate::resolver::context::WriteContext;
21use crate::resolver::type_resolver::TypeResolver;
22use crate::serializer::util::read_basic_type_info;
23use crate::serializer::ForyDefault;
24use crate::serializer::Serializer;
25use crate::types::TypeId;
26use crate::util::EPOCH;
27use chrono::{NaiveDate, NaiveDateTime};
28use std::mem;
29use std::time::Duration;
30
31impl Serializer for NaiveDateTime {
32    #[inline(always)]
33    fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
34        let dt = self.and_utc();
35        let seconds = dt.timestamp();
36        let nanos = dt.timestamp_subsec_nanos();
37        context.writer.write_i64(seconds);
38        context.writer.write_u32(nanos);
39        Ok(())
40    }
41
42    #[inline(always)]
43    fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error> {
44        let seconds = context.reader.read_i64()?;
45        let nanos = context.reader.read_u32()?;
46        #[allow(deprecated)]
47        let result = NaiveDateTime::from_timestamp(seconds, nanos);
48        Ok(result)
49    }
50
51    #[inline(always)]
52    fn fory_reserved_space() -> usize {
53        mem::size_of::<i64>() + mem::size_of::<u32>()
54    }
55
56    #[inline(always)]
57    fn fory_get_type_id(_: &TypeResolver) -> Result<TypeId, Error> {
58        Ok(TypeId::TIMESTAMP)
59    }
60
61    #[inline(always)]
62    fn fory_type_id_dyn(&self, _: &TypeResolver) -> Result<TypeId, Error> {
63        Ok(TypeId::TIMESTAMP)
64    }
65
66    #[inline(always)]
67    fn fory_static_type_id() -> TypeId {
68        TypeId::TIMESTAMP
69    }
70
71    #[inline(always)]
72    fn as_any(&self) -> &dyn std::any::Any {
73        self
74    }
75
76    #[inline(always)]
77    fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error> {
78        context.writer.write_u8(TypeId::TIMESTAMP as u8);
79        Ok(())
80    }
81
82    #[inline(always)]
83    fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
84        read_basic_type_info::<Self>(context)
85    }
86}
87
88impl Serializer for NaiveDate {
89    #[inline(always)]
90    fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
91        let days_since_epoch = self.signed_duration_since(EPOCH).num_days();
92        context.writer.write_i32(days_since_epoch as i32);
93        Ok(())
94    }
95
96    #[inline(always)]
97    fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error> {
98        let days = context.reader.read_i32()?;
99        use chrono::TimeDelta;
100        let duration = TimeDelta::days(days as i64);
101        let result = EPOCH + duration;
102        Ok(result)
103    }
104
105    #[inline(always)]
106    fn fory_reserved_space() -> usize {
107        mem::size_of::<i32>()
108    }
109
110    #[inline(always)]
111    fn fory_get_type_id(_: &TypeResolver) -> Result<TypeId, Error> {
112        Ok(TypeId::DATE)
113    }
114
115    #[inline(always)]
116    fn fory_type_id_dyn(&self, _: &TypeResolver) -> Result<TypeId, Error> {
117        Ok(TypeId::DATE)
118    }
119
120    #[inline(always)]
121    fn fory_static_type_id() -> TypeId {
122        TypeId::DATE
123    }
124
125    #[inline(always)]
126    fn as_any(&self) -> &dyn std::any::Any {
127        self
128    }
129
130    #[inline(always)]
131    fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error> {
132        context.writer.write_u8(TypeId::DATE as u8);
133        Ok(())
134    }
135
136    #[inline(always)]
137    fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
138        read_basic_type_info::<Self>(context)
139    }
140}
141
142impl ForyDefault for NaiveDateTime {
143    #[inline(always)]
144    fn fory_default() -> Self {
145        NaiveDateTime::default()
146    }
147}
148
149impl ForyDefault for NaiveDate {
150    #[inline(always)]
151    fn fory_default() -> Self {
152        NaiveDate::default()
153    }
154}
155
156impl Serializer for Duration {
157    #[inline(always)]
158    fn fory_write_data(&self, context: &mut WriteContext) -> Result<(), Error> {
159        let secs = self.as_secs() as i64;
160        let nanos = self.subsec_nanos() as i32;
161        context.writer.write_varint64(secs);
162        context.writer.write_i32(nanos);
163        Ok(())
164    }
165
166    #[inline(always)]
167    fn fory_read_data(context: &mut ReadContext) -> Result<Self, Error> {
168        let secs = context.reader.read_varint64()? as u64;
169        let nanos = context.reader.read_i32()? as u32;
170        Ok(Duration::new(secs, nanos))
171    }
172
173    #[inline(always)]
174    fn fory_reserved_space() -> usize {
175        9 + mem::size_of::<i32>() // max varint64 is 9 bytes + 4 bytes for i32
176    }
177
178    #[inline(always)]
179    fn fory_get_type_id(_: &TypeResolver) -> Result<TypeId, Error> {
180        Ok(TypeId::DURATION)
181    }
182
183    #[inline(always)]
184    fn fory_type_id_dyn(&self, _: &TypeResolver) -> Result<TypeId, Error> {
185        Ok(TypeId::DURATION)
186    }
187
188    #[inline(always)]
189    fn fory_static_type_id() -> TypeId {
190        TypeId::DURATION
191    }
192
193    #[inline(always)]
194    fn as_any(&self) -> &dyn std::any::Any {
195        self
196    }
197
198    #[inline(always)]
199    fn fory_write_type_info(context: &mut WriteContext) -> Result<(), Error> {
200        context.writer.write_u8(TypeId::DURATION as u8);
201        Ok(())
202    }
203
204    #[inline(always)]
205    fn fory_read_type_info(context: &mut ReadContext) -> Result<(), Error> {
206        read_basic_type_info::<Self>(context)
207    }
208}
209
210impl ForyDefault for Duration {
211    #[inline(always)]
212    fn fory_default() -> Self {
213        Duration::ZERO
214    }
215}
216
217#[cfg(test)]
218mod tests {
219    use super::*;
220    use crate::fory::Fory;
221
222    #[test]
223    fn test_duration_serialization() {
224        let fory = Fory::default();
225
226        // Test various durations
227        let test_cases = vec![
228            Duration::ZERO,
229            Duration::new(0, 0),
230            Duration::new(1, 0),
231            Duration::new(0, 1),
232            Duration::new(123, 456789),
233            Duration::new(u64::MAX, 999_999_999),
234        ];
235
236        for duration in test_cases {
237            let bytes = fory.serialize(&duration).unwrap();
238            let deserialized: Duration = fory.deserialize(&bytes).unwrap();
239            assert_eq!(
240                duration, deserialized,
241                "Failed for duration: {:?}",
242                duration
243            );
244        }
245    }
246}