allo_isolate/chrono.rs
1//! chrono types
2//!
3//! based on Dart VM, microseconds unit is used
4//!
5//! recommendations below implies UTC based conversions,
6//! as these are generally easier to work with.
7//! > see [timestamp_micros](https://docs.rs/chrono/0.4.20/chrono/naive/struct.NaiveDateTime.html?search=timestamp_micros#method.timestamp_micros)
8
9use crate::{
10 ffi::{DartCObject, DartHandleFinalizer, DartTypedDataType},
11 into_dart::{free_zero_copy_buffer_i64, DartTypedDataTypeTrait},
12 IntoDart,
13};
14
15impl IntoDart for chrono::DateTime<chrono::Utc> {
16 /// on the other side of FFI, value should be reconstructed like:
17 ///
18 /// - hydrate into Dart [DateTime](https://api.dart.dev/stable/2.18.0/dart-core/DateTime/DateTime.fromMicrosecondsSinceEpoch.html)
19 /// `DateTime.fromMicrosecondsSinceEpoch(raw, isUtc: true);`
20 ///
21 /// - hydrate into Rust [DateTime](chrono::DateTime)::<[Utc](chrono::Utc)>
22 /// ```rust,ignore
23 /// let s = (raw / 1_000_000) as i64;
24 /// let ns = (raw.rem_euclid(1_000_000) * 1_000) as u32;
25 /// chrono::DateTime::<chrono::Utc>::from_utc(
26 /// chrono::NaiveDateTime::from_timestamp(s, ns), chrono::Utc);
27 /// ```
28 ///
29 /// note that it could overflow under the same conditions as of [chrono::NaiveDateTime::from_timestamp](https://docs.rs/chrono/0.4.20/chrono/naive/struct.NaiveDateTime.html#method.from_timestamp)
30 fn into_dart(self) -> DartCObject {
31 self.timestamp_micros().into_dart()
32 }
33}
34
35impl IntoDart for chrono::DateTime<chrono::Local> {
36 /// on the other side of FFI, value should be reconstructed like:
37 ///
38 /// - hydrate into Dart [DateTime](https://api.dart.dev/stable/2.18.0/dart-core/DateTime/DateTime.fromMicrosecondsSinceEpoch.html)
39 /// `DateTime.fromMicrosecondsSinceEpoch(raw, isUtc: false);`
40 ///
41 /// - hydrate into Rust [DateTime](chrono::DateTime)::<[Local](chrono::Local)>
42 /// ```rust,ignore
43 /// let s = (raw / 1_000_000) as i64;
44 /// let ns = (raw.rem_euclid(1_000_000) * 1_000) as u32;
45 /// chrono::DateTime::<chrono::Local>::from(
46 /// chrono::DateTime::<chrono::Utc>::from_utc(
47 /// chrono::NaiveDateTime::from_timestamp(s, ns), chrono::Utc));
48 /// ```
49 ///
50 /// note that it could overflow under the same conditions as of [chrono::NaiveDateTime::from_timestamp](https://docs.rs/chrono/0.4.20/chrono/naive/struct.NaiveDateTime.html#method.from_timestamp)
51 fn into_dart(self) -> DartCObject {
52 self.timestamp_micros().into_dart()
53 }
54}
55
56impl IntoDart for chrono::NaiveDate {
57 /// on the other side of FFI, value should be reconstructed like:
58 ///
59 /// - hydrate into Dart [DateTime](https://api.dart.dev/stable/2.18.0/dart-core/DateTime/DateTime.fromMicrosecondsSinceEpoch.html)
60 /// `DateTime.fromMicrosecondsSinceEpoch(raw, isUtc: true);`
61 ///
62 /// - hydrate into Rust [NaiveDateTime](chrono::NaiveDate)
63 /// ```rust,ignore
64 /// let s = (raw / 1_000_000) as i64;
65 /// let ns = (raw.rem_euclid(1_000_000) * 1_000) as u32;
66 /// chrono::NaiveDateTime::from_timestamp(s, ns)
67 /// ```
68 ///
69 /// note that it could overflow under the same conditions as of [chrono::NaiveDateTime::from_timestamp](https://docs.rs/chrono/0.4.20/chrono/naive/struct.NaiveDateTime.html#method.from_timestamp)
70 fn into_dart(self) -> DartCObject {
71 self.signed_duration_since(chrono::NaiveDate::MIN)
72 .into_dart()
73 }
74}
75
76impl IntoDart for chrono::NaiveDateTime {
77 /// on the other side of FFI, value should be reconstructed like:
78 ///
79 /// - hydrate into Dart [DateTime](https://api.dart.dev/stable/2.18.0/dart-core/DateTime/DateTime.fromMicrosecondsSinceEpoch.html)
80 /// `DateTime.fromMicrosecondsSinceEpoch(raw, isUtc: true);`
81 ///
82 /// - hydrate into Rust [NaiveDateTime](chrono::NaiveDateTime)
83 /// ```rust,ignore
84 /// let s = (raw / 1_000_000) as i64;
85 /// let ns = (raw.rem_euclid(1_000_000) * 1_000) as u32;
86 /// chrono::NaiveDateTime::from_timestamp(s, ns)
87 /// ```
88 ///
89 /// note that it could overflow under the same conditions as of [chrono::NaiveDateTime::from_timestamp](https://docs.rs/chrono/0.4.20/chrono/naive/struct.NaiveDateTime.html#method.from_timestamp)
90 fn into_dart(self) -> DartCObject {
91 self.timestamp_micros().into_dart()
92 }
93}
94
95impl IntoDart for chrono::Duration {
96 /// on the other side of FFI, value should be reconstructed like:
97 ///
98 /// - hydrate into Dart [Duration](https://api.dart.dev/stable/2.18.0/dart-core/Duration/Duration.html)
99 /// `Duration(microseconds: raw);`
100 ///
101 /// - hydrate into Rust [Duration](chrono::Duration)
102 /// `chrono::Duration::microseconds(raw);`
103 fn into_dart(self) -> DartCObject {
104 self.num_microseconds().into_dart()
105 }
106}
107
108impl IntoDart for Vec<chrono::DateTime<chrono::Utc>> {
109 fn into_dart(self) -> DartCObject {
110 self.iter()
111 .map(chrono::DateTime::<chrono::Utc>::timestamp_micros)
112 .collect::<Vec<_>>()
113 .into_dart()
114 }
115}
116
117impl<const N: usize> IntoDart for [chrono::DateTime<chrono::Utc>; N] {
118 fn into_dart(self) -> DartCObject {
119 let vec: Vec<_> = self.into();
120 vec.into_dart()
121 }
122}
123
124impl DartTypedDataTypeTrait for chrono::DateTime<chrono::Utc> {
125 fn dart_typed_data_type() -> DartTypedDataType {
126 DartTypedDataType::Int64
127 }
128
129 fn function_pointer_of_free_zero_copy_buffer() -> DartHandleFinalizer {
130 free_zero_copy_buffer_i64
131 }
132}
133
134impl IntoDart for Vec<chrono::DateTime<chrono::Local>> {
135 fn into_dart(self) -> DartCObject {
136 self.iter()
137 .map(chrono::DateTime::<chrono::Local>::timestamp_micros)
138 .collect::<Vec<_>>()
139 .into_dart()
140 }
141}
142
143impl<const N: usize> IntoDart for [chrono::DateTime<chrono::Local>; N] {
144 fn into_dart(self) -> DartCObject {
145 let vec: Vec<_> = self.into();
146 vec.into_dart()
147 }
148}
149
150impl DartTypedDataTypeTrait for chrono::DateTime<chrono::Local> {
151 fn dart_typed_data_type() -> DartTypedDataType {
152 DartTypedDataType::Int64
153 }
154
155 fn function_pointer_of_free_zero_copy_buffer() -> DartHandleFinalizer {
156 free_zero_copy_buffer_i64
157 }
158}
159
160impl IntoDart for Vec<chrono::NaiveDate> {
161 fn into_dart(self) -> DartCObject {
162 self.iter()
163 .map(|lhs| lhs.signed_duration_since(chrono::NaiveDate::MIN))
164 .collect::<Vec<_>>()
165 .into_dart()
166 }
167}
168
169impl<const N: usize> IntoDart for [chrono::NaiveDate; N] {
170 fn into_dart(self) -> DartCObject {
171 let vec: Vec<_> = self.into();
172 vec.into_dart()
173 }
174}
175
176impl DartTypedDataTypeTrait for chrono::NaiveDate {
177 fn dart_typed_data_type() -> DartTypedDataType {
178 DartTypedDataType::Int64
179 }
180
181 fn function_pointer_of_free_zero_copy_buffer() -> DartHandleFinalizer {
182 free_zero_copy_buffer_i64
183 }
184}
185
186impl IntoDart for Vec<chrono::NaiveDateTime> {
187 fn into_dart(self) -> DartCObject {
188 self.iter()
189 .map(chrono::NaiveDateTime::timestamp_micros)
190 .collect::<Vec<_>>()
191 .into_dart()
192 }
193}
194
195impl<const N: usize> IntoDart for [chrono::NaiveDateTime; N] {
196 fn into_dart(self) -> DartCObject {
197 let vec: Vec<_> = self.into();
198 vec.into_dart()
199 }
200}
201
202impl DartTypedDataTypeTrait for chrono::NaiveDateTime {
203 fn dart_typed_data_type() -> DartTypedDataType {
204 DartTypedDataType::Int64
205 }
206
207 fn function_pointer_of_free_zero_copy_buffer() -> DartHandleFinalizer {
208 free_zero_copy_buffer_i64
209 }
210}
211
212impl IntoDart for Vec<chrono::Duration> {
213 fn into_dart(self) -> DartCObject {
214 self.iter()
215 .map(chrono::Duration::num_microseconds)
216 .collect::<Vec<_>>()
217 .into_dart()
218 }
219}
220
221impl<const N: usize> IntoDart for [chrono::Duration; N] {
222 fn into_dart(self) -> DartCObject {
223 let vec: Vec<_> = self.into();
224 vec.into_dart()
225 }
226}