//! Treat an [`OffsetDateTime`] as a [Unix timestamp] with milliseconds for //! the purposes of serde. //! //! Use this module in combination with serde's [`#[with]`][with] attribute. //! //! When deserializing, the offset is assumed to be UTC. //! //! [Unix timestamp]: https://en.wikipedia.org/wiki/Unix_time //! [with]: https://serde.rs/field-attrs.html#with use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; use crate::OffsetDateTime; /// Serialize an `OffsetDateTime` as its Unix timestamp with milliseconds pub fn serialize( datetime: &OffsetDateTime, serializer: S, ) -> Result { let timestamp = datetime.unix_timestamp_nanos() / 1_000_000; timestamp.serialize(serializer) } /// Deserialize an `OffsetDateTime` from its Unix timestamp with milliseconds pub fn deserialize<'a, D: Deserializer<'a>>(deserializer: D) -> Result { let value: i128 = <_>::deserialize(deserializer)?; OffsetDateTime::from_unix_timestamp_nanos(value * 1_000_000) .map_err(|err| de::Error::invalid_value(de::Unexpected::Signed(err.value), &err)) } /// Treat an `Option` as a [Unix timestamp] with milliseconds /// for the purposes of serde. /// /// Use this module in combination with serde's [`#[with]`][with] attribute. /// /// When deserializing, the offset is assumed to be UTC. /// /// [Unix timestamp]: https://en.wikipedia.org/wiki/Unix_time /// [with]: https://serde.rs/field-attrs.html#with pub mod option { #[allow(clippy::wildcard_imports)] use super::*; /// Serialize an `Option` as its Unix timestamp with milliseconds pub fn serialize( option: &Option, serializer: S, ) -> Result { option .map(|timestamp| timestamp.unix_timestamp_nanos() / 1_000_000) .serialize(serializer) } /// Deserialize an `Option` from its Unix timestamp with milliseconds pub fn deserialize<'a, D: Deserializer<'a>>( deserializer: D, ) -> Result, D::Error> { Option::deserialize(deserializer)? .map(|value: i128| OffsetDateTime::from_unix_timestamp_nanos(value * 1_000_000)) .transpose() .map_err(|err| de::Error::invalid_value(de::Unexpected::Signed(err.value), &err)) } }