iodeser/times/
mod.rs

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}