1#![doc(html_root_url = "https://docs.rs/humantime-serde/1.0")]
2#![forbid(unsafe_code)]
3
4pub mod re {
40 pub use humantime;
41}
42
43pub mod option;
44
45use std::fmt;
46use std::ops::{Deref, DerefMut};
47use std::time::{Duration, SystemTime};
48
49use humantime;
50use serde::{de, ser, Deserialize, Deserializer, Serialize, Serializer};
51
52pub fn deserialize<'a, T, D>(d: D) -> Result<T, D::Error>
57where
58 Serde<T>: Deserialize<'a>,
59 D: Deserializer<'a>,
60{
61 Serde::deserialize(d).map(Serde::into_inner)
62}
63
64pub fn serialize<T, S>(d: &T, s: S) -> Result<S::Ok, S::Error>
69where
70 for<'a> Serde<&'a T>: Serialize,
71 S: Serializer,
72{
73 Serde::from(d).serialize(s)
74}
75
76#[derive(Copy, Clone, Eq, Hash, PartialEq)]
79pub struct Serde<T>(T);
80
81impl<T> fmt::Debug for Serde<T>
82where
83 T: fmt::Debug,
84{
85 fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
86 self.0.fmt(formatter)
87 }
88}
89
90impl<T> Deref for Serde<T> {
91 type Target = T;
92
93 fn deref(&self) -> &T {
94 &self.0
95 }
96}
97
98impl<T> DerefMut for Serde<T> {
99 fn deref_mut(&mut self) -> &mut T {
100 &mut self.0
101 }
102}
103
104impl<T> Serde<T> {
105 pub fn into_inner(self) -> T {
107 self.0
108 }
109}
110
111impl<T> From<T> for Serde<T> {
112 fn from(val: T) -> Serde<T> {
113 Serde(val)
114 }
115}
116
117impl<'de> Deserialize<'de> for Serde<Duration> {
118 fn deserialize<D>(d: D) -> Result<Serde<Duration>, D::Error>
119 where
120 D: Deserializer<'de>,
121 {
122 struct V;
123
124 impl<'de2> de::Visitor<'de2> for V {
125 type Value = Duration;
126
127 fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
128 fmt.write_str("a duration")
129 }
130
131 fn visit_str<E>(self, v: &str) -> Result<Duration, E>
132 where
133 E: de::Error,
134 {
135 humantime::parse_duration(v).map_err(|_| {
136 E::invalid_value(de::Unexpected::Str(v), &self)
137 })
138 }
139 }
140
141 d.deserialize_str(V).map(Serde)
142 }
143}
144
145impl<'de> Deserialize<'de> for Serde<SystemTime> {
146 fn deserialize<D>(d: D) -> Result<Serde<SystemTime>, D::Error>
147 where
148 D: Deserializer<'de>,
149 {
150 struct V;
151
152 impl<'de2> de::Visitor<'de2> for V {
153 type Value = SystemTime;
154
155 fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
156 fmt.write_str("a timestamp")
157 }
158
159 fn visit_str<E>(self, v: &str) -> Result<SystemTime, E>
160 where
161 E: de::Error,
162 {
163 humantime::parse_rfc3339_weak(v).map_err(|_| {
164 E::invalid_value(de::Unexpected::Str(v), &self)
165 })
166 }
167 }
168
169 d.deserialize_str(V).map(Serde)
170 }
171}
172
173impl<'de> Deserialize<'de> for Serde<Option<Duration>> {
174 fn deserialize<D>(d: D) -> Result<Serde<Option<Duration>>, D::Error>
175 where
176 D: Deserializer<'de>,
177 {
178 match Option::<Serde<Duration>>::deserialize(d)? {
179 Some(Serde(dur)) => Ok(Serde(Some(dur))),
180 None => Ok(Serde(None)),
181 }
182 }
183}
184
185impl<'de> Deserialize<'de> for Serde<Option<SystemTime>> {
186 fn deserialize<D>(d: D) -> Result<Serde<Option<SystemTime>>, D::Error>
187 where
188 D: Deserializer<'de>,
189 {
190 match Option::<Serde<SystemTime>>::deserialize(d)? {
191 Some(Serde(dur)) => Ok(Serde(Some(dur))),
192 None => Ok(Serde(None)),
193 }
194 }
195}
196
197impl<'a> ser::Serialize for Serde<&'a Duration> {
198 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
199 where
200 S: ser::Serializer,
201 {
202 humantime::format_duration(*self.0)
203 .to_string()
204 .serialize(serializer)
205 }
206}
207
208impl ser::Serialize for Serde<Duration> {
209 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
210 where
211 S: ser::Serializer,
212 {
213 humantime::format_duration(self.0)
214 .to_string()
215 .serialize(serializer)
216 }
217}
218
219impl<'a> ser::Serialize for Serde<&'a SystemTime> {
220 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
221 where
222 S: ser::Serializer,
223 {
224 humantime::format_rfc3339(*self.0)
225 .to_string()
226 .serialize(serializer)
227 }
228}
229
230impl ser::Serialize for Serde<SystemTime> {
231 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
232 where
233 S: ser::Serializer,
234 {
235 humantime::format_rfc3339(self.0)
236 .to_string()
237 .serialize(serializer)
238 }
239}
240
241impl<'a> ser::Serialize for Serde<&'a Option<Duration>> {
242 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
243 where
244 S: ser::Serializer,
245 {
246 match *self.0 {
247 Some(dur) => serializer.serialize_some(&Serde(dur)),
248 None => serializer.serialize_none(),
249 }
250 }
251}
252
253impl ser::Serialize for Serde<Option<Duration>> {
254 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
255 where
256 S: ser::Serializer,
257 {
258 Serde(&self.0).serialize(serializer)
259 }
260}
261
262impl<'a> ser::Serialize for Serde<&'a Option<SystemTime>> {
263 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
264 where
265 S: ser::Serializer,
266 {
267 match *self.0 {
268 Some(tm) => serializer.serialize_some(&Serde(tm)),
269 None => serializer.serialize_none(),
270 }
271 }
272}
273
274impl ser::Serialize for Serde<Option<SystemTime>> {
275 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
276 where
277 S: ser::Serializer,
278 {
279 Serde(&self.0).serialize(serializer)
280 }
281}
282
283#[cfg(test)]
284mod test {
285 use super::*;
286 use std::time::{SystemTime, UNIX_EPOCH};
287
288 #[test]
289 fn with() {
290 #[derive(Serialize, Deserialize)]
291 struct Foo {
292 #[serde(with = "super")]
293 time: Duration,
294 }
295
296 let json = r#"{"time": "15 seconds"}"#;
297 let foo = serde_json::from_str::<Foo>(json).unwrap();
298 assert_eq!(foo.time, Duration::from_secs(15));
299 let reverse = serde_json::to_string(&foo).unwrap();
300 assert_eq!(reverse, r#"{"time":"15s"}"#);
301 }
302
303 #[test]
304 fn with_option() {
305 #[derive(Serialize, Deserialize)]
306 struct Foo {
307 #[serde(with = "super", default)]
308 time: Option<Duration>,
309 }
310
311 let json = r#"{"time": "15 seconds"}"#;
312 let foo = serde_json::from_str::<Foo>(json).unwrap();
313 assert_eq!(foo.time, Some(Duration::from_secs(15)));
314 let reverse = serde_json::to_string(&foo).unwrap();
315 assert_eq!(reverse, r#"{"time":"15s"}"#);
316
317 let json = r#"{"time": null}"#;
318 let foo = serde_json::from_str::<Foo>(json).unwrap();
319 assert_eq!(foo.time, None);
320 let reverse = serde_json::to_string(&foo).unwrap();
321 assert_eq!(reverse, r#"{"time":null}"#);
322
323 let json = r#"{}"#;
324 let foo = serde_json::from_str::<Foo>(json).unwrap();
325 assert_eq!(foo.time, None);
326 }
327
328 #[test]
329 fn time() {
330 #[derive(Serialize, Deserialize)]
331 struct Foo {
332 #[serde(with = "super")]
333 time: SystemTime,
334 }
335
336 let json = r#"{"time": "2018-05-11 18:28:30"}"#;
337 let foo = serde_json::from_str::<Foo>(json).unwrap();
338 assert_eq!(foo.time, UNIX_EPOCH + Duration::new(1526063310, 0));
339 let reverse = serde_json::to_string(&foo).unwrap();
340 assert_eq!(reverse, r#"{"time":"2018-05-11T18:28:30Z"}"#);
341 }
342
343 #[test]
344 fn time_with_option() {
345 #[derive(Serialize, Deserialize)]
346 struct Foo {
347 #[serde(with = "super", default)]
348 time: Option<SystemTime>,
349 }
350
351 let json = r#"{"time": "2018-05-11 18:28:30"}"#;
352 let foo = serde_json::from_str::<Foo>(json).unwrap();
353 assert_eq!(foo.time, Some(UNIX_EPOCH + Duration::new(1526063310, 0)));
354 let reverse = serde_json::to_string(&foo).unwrap();
355 assert_eq!(reverse, r#"{"time":"2018-05-11T18:28:30Z"}"#);
356
357 let json = r#"{"time": null}"#;
358 let foo = serde_json::from_str::<Foo>(json).unwrap();
359 assert_eq!(foo.time, None);
360 let reverse = serde_json::to_string(&foo).unwrap();
361 assert_eq!(reverse, r#"{"time":null}"#);
362
363 let json = r#"{}"#;
364 let foo = serde_json::from_str::<Foo>(json).unwrap();
365 assert_eq!(foo.time, None);
366 }
367
368 #[test]
369 fn test_readme_deps() {
370 version_sync::assert_markdown_deps_updated!("README.md");
371 }
372
373 #[test]
374 fn test_html_root_url() {
375 version_sync::assert_html_root_url_updated!("src/lib.rs");
376 }
377}