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 = "formatting")]
12use serde::ser::Error as _;
13#[cfg(feature = "parsing")]
14use serde::Deserializer;
15#[cfg(feature = "formatting")]
16use serde::{Serialize, Serializer};
17
18#[cfg(feature = "parsing")]
19use super::Visitor;
20use crate::format_description::well_known::Rfc3339;
21use crate::OffsetDateTime;
22
23/// Serialize an [`OffsetDateTime`] using the well-known RFC3339 format.
24#[cfg(feature = "formatting")]
25#[inline]
26pub fn serialize<S: Serializer>(
27    datetime: &OffsetDateTime,
28    serializer: S,
29) -> Result<S::Ok, S::Error> {
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<'a>>(deserializer: D) -> Result<OffsetDateTime, D::Error> {
40    deserializer.deserialize_str(Visitor::<Rfc3339>(PhantomData))
41}
42
43/// Use the well-known [RFC3339 format] when serializing and deserializing an
44/// [`Option<OffsetDateTime>`].
45///
46/// Use this module in combination with serde's [`#[with]`][with] attribute.
47///
48/// [RFC3339 format]: https://tools.ietf.org/html/rfc3339#section-5.6
49/// [with]: https://serde.rs/field-attrs.html#with
50pub mod option {
51    use super::*;
52
53    /// Serialize an [`Option<OffsetDateTime>`] using the well-known RFC3339 format.
54    #[cfg(feature = "formatting")]
55    #[inline]
56    pub fn serialize<S: Serializer>(
57        option: &Option<OffsetDateTime>,
58        serializer: S,
59    ) -> Result<S::Ok, S::Error> {
60        option
61            .map(|odt| odt.format(&Rfc3339))
62            .transpose()
63            .map_err(S::Error::custom)?
64            .serialize(serializer)
65    }
66
67    /// Deserialize an [`Option<OffsetDateTime>`] from its RFC3339 representation.
68    #[cfg(feature = "parsing")]
69    #[inline]
70    pub fn deserialize<'a, D: Deserializer<'a>>(
71        deserializer: D,
72    ) -> Result<Option<OffsetDateTime>, D::Error> {
73        deserializer.deserialize_option(Visitor::<Option<Rfc3339>>(PhantomData))
74    }
75}