time/serde/timestamp/nanoseconds.rs
1//! Treat an [`OffsetDateTime`] as a [Unix timestamp] with nanoseconds for
2//! the purposes of serde.
3//!
4//! Use this module in combination with serde's [`#[with]`][with] attribute.
5//!
6//! When deserializing, the offset is assumed to be UTC.
7//!
8//! [Unix timestamp]: https://en.wikipedia.org/wiki/Unix_time
9//! [with]: https://serde.rs/field-attrs.html#with
10
11use serde_core::{Deserialize, Deserializer, Serialize, Serializer};
12
13use crate::OffsetDateTime;
14use crate::error::ComponentRange;
15
16/// Serialize an `OffsetDateTime` as its Unix timestamp with nanoseconds
17#[inline]
18pub fn serialize<S>(datetime: &OffsetDateTime, serializer: S) -> Result<S::Ok, S::Error>
19where
20 S: Serializer,
21{
22 datetime.unix_timestamp_nanos().serialize(serializer)
23}
24
25/// Deserialize an `OffsetDateTime` from its Unix timestamp with nanoseconds
26#[inline]
27pub fn deserialize<'a, D>(deserializer: D) -> Result<OffsetDateTime, D::Error>
28where
29 D: Deserializer<'a>,
30{
31 OffsetDateTime::from_unix_timestamp_nanos(<_>::deserialize(deserializer)?)
32 .map_err(ComponentRange::into_de_error)
33}
34
35/// Treat an `Option<OffsetDateTime>` as a [Unix timestamp] with nanoseconds
36/// for the purposes of serde.
37///
38/// Use this module in combination with serde's [`#[with]`][with] attribute.
39///
40/// Note: Due to [serde-rs/serde#2878], you will need to apply `#[serde(default)]` if you want a
41/// missing field to deserialize as `None`.
42///
43/// When deserializing, the offset is assumed to be UTC.
44///
45/// [Unix timestamp]: https://en.wikipedia.org/wiki/Unix_time
46/// [with]: https://serde.rs/field-attrs.html#with
47/// [serde-rs/serde#2878]: https://github.com/serde-rs/serde/issues/2878
48pub mod option {
49 use super::*;
50
51 /// Serialize an `Option<OffsetDateTime>` as its Unix timestamp with nanoseconds
52 #[inline]
53 pub fn serialize<S>(option: &Option<OffsetDateTime>, serializer: S) -> Result<S::Ok, S::Error>
54 where
55 S: Serializer,
56 {
57 option
58 .map(OffsetDateTime::unix_timestamp_nanos)
59 .serialize(serializer)
60 }
61
62 /// Deserialize an `Option<OffsetDateTime>` from its Unix timestamp with nanoseconds
63 #[inline]
64 pub fn deserialize<'a, D>(deserializer: D) -> Result<Option<OffsetDateTime>, D::Error>
65 where
66 D: Deserializer<'a>,
67 {
68 Option::deserialize(deserializer)?
69 .map(OffsetDateTime::from_unix_timestamp_nanos)
70 .transpose()
71 .map_err(ComponentRange::into_de_error)
72 }
73}