1#[cfg(feature = "chrono")]
2use chrono::TimeDelta;
3use std::time::{Duration, SystemTime, UNIX_EPOCH};
4use std::fmt::Write;
5
6use crate::{delete_tabulator, from_io, IoDeSer};
7
8#[automatically_derived]
9impl IoDeSer for Duration {
10 fn to_io_string(&self, tab: u8, buffer: &mut String) {
11 let tab = (0..tab).map(|_| "\t").collect::<String>();
12 let _ = write!(
13 buffer,
14 "|
15{}\tseconds->|{}|
16{}\tnanoseconds->|{}|
17{}|",
18 &tab,
19 self.as_secs(),
20 &tab,
21 self.as_nanos(),
22 tab
23 );
24 }
25
26 fn from_io_string(io_input: &mut String) -> crate::Result<Self>
27 where
28 Self: Sized,
29 {
30 let _ = delete_tabulator(io_input)?;
31
32 let l = io_input
33 .trim()
34 .split_terminator('\n')
35 .collect::<Vec<&str>>();
36
37 if l.len() != 2 {
38 return Err(
39 crate::Error::io_format(io_input.to_string(), format!("Wrong number of line encountered in the passed io string. Expected 2, received {}.",l.len())).into()
40 );
41 }
42
43 let seconds = l[0].trim();
44 let nano_seconds = l[1].trim();
45
46 if !seconds.starts_with("seconds->|") || !nano_seconds.starts_with("nanoseconds->|") {
47 return Err(
48 crate::Error::io_format(io_input.to_string(), "Fields 'seconds' or 'nanoseconds' were not found during Duration type deserialization.".to_string()).into()
49 );
50 }
51
52 let seconds = from_io!(seconds.split("->").nth(1).unwrap().to_string(), u64)?;
53 let nano_seconds = from_io!(nano_seconds.split("->").nth(1).unwrap().to_string(), u128)?;
54
55 Ok(Duration::new(seconds, nano_seconds as u32))
56 }
57}
58
59#[automatically_derived]
60impl IoDeSer for SystemTime {
61 #[inline]
62 fn to_io_string(&self, tab: u8, buffer: &mut String) {
63 self.duration_since(UNIX_EPOCH)
64 .expect("TODO - handle this error better")
65 .to_io_string(tab, buffer);
66 }
67
68 #[inline]
69 fn from_io_string(io_input: &mut String) -> crate::Result<Self>
70 where
71 Self: Sized,
72 {
73 Ok(UNIX_EPOCH + from_io!(io_input, Duration)?)
74 }
75}
76
77#[cfg(feature = "chrono")]
78#[automatically_derived]
79impl IoDeSer for chrono::DateTime<chrono::Utc> {
80 fn to_io_string(&self, _tab: u8, buffer: &mut String) {
81 let _ = write!(buffer, "|{}|", &self.to_rfc3339());
82 }
83
84 #[inline]
85 fn from_io_string(io_input: &mut String) -> crate::Result<Self>
86 where
87 Self: Sized,
88 {
89 Ok(
90 chrono::DateTime::parse_from_rfc3339(from_io!(io_input, &str)?)
91 .map_err(|e| crate::errors::Error::io_format(io_input.to_string(), e.to_string()))?
92 .to_utc(),
93 )
94 }
95}
96
97#[cfg(feature = "chrono")]
98#[automatically_derived]
99impl IoDeSer for chrono::DateTime<chrono::FixedOffset> {
100 fn to_io_string(&self, _tab: u8, buffer: &mut String) {
101 let _ = write!(buffer, "|{}|", &self.to_rfc3339());
102 }
103
104 #[inline]
105 fn from_io_string(io_input: &mut String) -> crate::Result<Self>
106 where
107 Self: Sized,
108 {
109 Ok(
110 chrono::DateTime::parse_from_rfc3339(from_io!(io_input, &str)?).map_err(|e| {
111 crate::errors::Error::io_format(io_input.to_string(), e.to_string())
112 })?,
113 )
114 }
115}
116
117#[cfg(feature = "chrono")]
118#[automatically_derived]
119impl IoDeSer for chrono::DateTime<chrono::Local> {
120 fn to_io_string(&self, _tab: u8, buffer: &mut String) {
121 let _ = write!(buffer, "|{}|", &self.to_rfc3339());
122 }
123
124 #[inline]
125 fn from_io_string(io_input: &mut String) -> crate::Result<Self>
126 where
127 Self: Sized,
128 {
129 Ok(chrono::DateTime::<chrono::Local>::from(from_io!(
130 io_input,
131 chrono::DateTime<chrono::FixedOffset>
132 )?))
133 }
134}
135
136#[cfg(feature = "chrono")]
137#[automatically_derived]
138impl IoDeSer for chrono::NaiveDate {
139 fn to_io_string(&self, _tab: u8, buffer: &mut String) {
140 let _ = write!(buffer, "|{}|", &self.format("%Y-%m-%dT00:00:00.00+00:00"));
141 }
142
143 #[inline]
144 fn from_io_string(io_input: &mut String) -> crate::Result<Self>
145 where
146 Self: Sized,
147 {
148 Ok(
149 chrono::NaiveDate::parse_from_str(from_io!(io_input, &str)?, "%Y-%m-%dT%H:%M:%S%.f+%Z")
150 .map_err(|e| {
151 crate::errors::Error::io_format(io_input.to_string(), e.to_string())
152 })?,
153 )
154 }
155}
156
157#[cfg(feature = "chrono")]
158#[automatically_derived]
159impl IoDeSer for chrono::NaiveDateTime {
160 fn to_io_string(&self, _tab: u8, buffer: &mut String) {
161 let _ = write!(buffer, "|{}|", &self.format("%Y-%m-%dT%H:%M:%S%.f+00:00"));
162 }
163
164 #[inline]
165 fn from_io_string(io_input: &mut String) -> crate::Result<Self>
166 where
167 Self: Sized,
168 {
169 Ok(chrono::NaiveDateTime::parse_from_str(
170 from_io!(io_input, &str)?,
171 "%Y-%m-%dT%H:%M:%S%.f+%Z",
172 )
173 .map_err(|e| crate::errors::Error::io_format(io_input.to_string(), e.to_string()))?)
174 }
175}
176
177#[cfg(feature = "chrono")]
178#[automatically_derived]
179impl IoDeSer for chrono::TimeDelta {
180 fn to_io_string(&self, tab: u8, buffer: &mut String) {
181 self.to_std().unwrap().to_io_string(tab, buffer);
182 }
183
184 #[inline]
185 fn from_io_string(io_input: &mut String) -> crate::Result<Self>
186 where
187 Self: Sized,
188 {
189 Ok(TimeDelta::from_std(from_io!(io_input, Duration)?).unwrap())
190 }
191}
192
193#[cfg(feature = "chrono")]
194#[automatically_derived]
195impl IoDeSer for chrono::NaiveTime {
196 fn to_io_string(&self, _tab: u8, buffer: &mut String) {
197 let _ = write!(buffer, "|{}|", self.format("1970-01-01T%H:%M:%S%.f+00:00"));
198 }
199
200 #[inline]
201 fn from_io_string(io_input: &mut String) -> crate::Result<Self>
202 where
203 Self: Sized,
204 {
205 Ok(
206 chrono::NaiveTime::parse_from_str(from_io!(io_input, &str)?, "%Y-%m-%dT%H:%M:%S%.f+%Z")
207 .map_err(|e| {
208 crate::errors::Error::io_format(io_input.to_string(), e.to_string())
209 })?,
210 )
211 }
212}