time/serde/
rfc3339.rs

1//! Use the well-known [RFC3339 format] when serializing and deserializing an [`OffsetDateTime`].
2//!
3//! Use this module in combination with serde's [`#[with]`][with] attribute.
4//!
5//! [RFC3339 format]: https://tools.ietf.org/html/rfc3339#section-5.6
6//! [with]: https://serde.rs/field-attrs.html#with
7
8#[cfg(feature = "parsing")]
9use core::marker::PhantomData;
10
11#[cfg(feature = "parsing")]
12use serde_core::Deserializer;
13#[cfg(feature = "formatting")]
14use serde_core::ser::Error as _;
15#[cfg(feature = "formatting")]
16use serde_core::{Serialize, Serializer};
17
18#[cfg(feature = "parsing")]
19use super::Visitor;
20use crate::OffsetDateTime;
21use crate::format_description::well_known::Rfc3339;
22
23/// Serialize an [`OffsetDateTime`] using the well-known RFC3339 format.
24#[cfg(feature = "formatting")]
25#[inline]
26pub fn serialize<S>(datetime: &OffsetDateTime, serializer: S) -> Result<S::Ok, S::Error>
27where
28    S: Serializer,
29{
30    datetime
31        .format(&Rfc3339)
32        .map_err(S::Error::custom)?
33        .serialize(serializer)
34}
35
36/// Deserialize an [`OffsetDateTime`] from its RFC3339 representation.
37#[cfg(feature = "parsing")]
38#[inline]
39pub fn deserialize<'a, D>(deserializer: D) -> Result<OffsetDateTime, D::Error>
40where
41    D: Deserializer<'a>,
42{
43    deserializer.deserialize_str(Visitor::<Rfc3339>(PhantomData))
44}
45
46/// Use the well-known [RFC3339 format] when serializing and deserializing an
47/// [`Option<OffsetDateTime>`].
48///
49/// Use this module in combination with serde's [`#[with]`][with] attribute.
50///
51/// Note: Due to [serde-rs/serde#2878], you will need to apply `#[serde(default)]` if you want a
52/// missing field to deserialize as `None`.
53///
54/// [RFC3339 format]: https://tools.ietf.org/html/rfc3339#section-5.6
55/// [with]: https://serde.rs/field-attrs.html#with
56/// [serde-rs/serde#2878]: https://github.com/serde-rs/serde/issues/2878
57pub mod option {
58    use super::*;
59
60    /// Serialize an [`Option<OffsetDateTime>`] using the well-known RFC3339 format.
61    #[cfg(feature = "formatting")]
62    #[inline]
63    pub fn serialize<S>(option: &Option<OffsetDateTime>, serializer: S) -> Result<S::Ok, S::Error>
64    where
65        S: Serializer,
66    {
67        option
68            .map(|odt| odt.format(&Rfc3339))
69            .transpose()
70            .map_err(S::Error::custom)?
71            .serialize(serializer)
72    }
73
74    /// Deserialize an [`Option<OffsetDateTime>`] from its RFC3339 representation.
75    #[cfg(feature = "parsing")]
76    #[inline]
77    pub fn deserialize<'a, D>(deserializer: D) -> Result<Option<OffsetDateTime>, D::Error>
78    where
79        D: Deserializer<'a>,
80    {
81        deserializer.deserialize_option(Visitor::<Option<Rfc3339>>(PhantomData))
82    }
83}