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}