time/serde/
iso8601.rs

1//! Use the well-known [ISO 8601 format] when serializing and deserializing an [`OffsetDateTime`].
2//!
3//! Use this module in combination with serde's [`#[with]`][with] attribute.
4//!
5//! [ISO 8601 format]: https://www.iso.org/iso-8601-date-and-time-format.html
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::iso8601::{Config, EncodedConfig};
21use crate::format_description::well_known::Iso8601;
22use crate::OffsetDateTime;
23
24/// The configuration of ISO 8601 used for serde implementations.
25pub(crate) const SERDE_CONFIG: EncodedConfig =
26    Config::DEFAULT.set_year_is_six_digits(true).encode();
27
28/// Serialize an [`OffsetDateTime`] using the well-known ISO 8601 format.
29#[cfg(feature = "formatting")]
30pub fn serialize<S: Serializer>(
31    datetime: &OffsetDateTime,
32    serializer: S,
33) -> Result<S::Ok, S::Error> {
34    datetime
35        .format(&Iso8601::<SERDE_CONFIG>)
36        .map_err(S::Error::custom)?
37        .serialize(serializer)
38}
39
40/// Deserialize an [`OffsetDateTime`] from its ISO 8601 representation.
41#[cfg(feature = "parsing")]
42pub fn deserialize<'a, D: Deserializer<'a>>(deserializer: D) -> Result<OffsetDateTime, D::Error> {
43    deserializer.deserialize_str(Visitor::<Iso8601<SERDE_CONFIG>>(PhantomData))
44}
45
46/// Use the well-known ISO 8601 format when serializing and deserializing an
47/// [`Option<OffsetDateTime>`].
48///
49/// Use this module in combination with serde's [`#[with]`][with] attribute.
50///
51/// [ISO 8601 format]: https://www.iso.org/iso-8601-date-and-time-format.html
52/// [with]: https://serde.rs/field-attrs.html#with
53pub mod option {
54    use super::*;
55
56    /// Serialize an [`Option<OffsetDateTime>`] using the well-known ISO 8601 format.
57    #[cfg(feature = "formatting")]
58    pub fn serialize<S: Serializer>(
59        option: &Option<OffsetDateTime>,
60        serializer: S,
61    ) -> Result<S::Ok, S::Error> {
62        option
63            .map(|odt| odt.format(&Iso8601::<SERDE_CONFIG>))
64            .transpose()
65            .map_err(S::Error::custom)?
66            .serialize(serializer)
67    }
68
69    /// Deserialize an [`Option<OffsetDateTime>`] from its ISO 8601 representation.
70    #[cfg(feature = "parsing")]
71    pub fn deserialize<'a, D: Deserializer<'a>>(
72        deserializer: D,
73    ) -> Result<Option<OffsetDateTime>, D::Error> {
74        deserializer.deserialize_option(Visitor::<Option<Iso8601<SERDE_CONFIG>>>(PhantomData))
75    }
76}