Skip to content

Commit

Permalink
Do not use Offset's Debug impl when serializing DateTime
Browse files Browse the repository at this point in the history
  • Loading branch information
pitdicker committed Apr 24, 2023
1 parent c2615dc commit e160979
Showing 1 changed file with 18 additions and 8 deletions.
26 changes: 18 additions & 8 deletions src/datetime/serde.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#![cfg_attr(docsrs, doc(cfg(feature = "serde")))]

use core::fmt;
use core::fmt::{Debug, Write};
use serde::{de, ser};

use super::DateTime;
use crate::naive::datetime::serde::serde_from;
#[cfg(feature = "clock")]
use crate::offset::Local;
use crate::offset::{FixedOffset, TimeZone, Utc};
use crate::offset::{FixedOffset, Offset, TimeZone, Utc};

#[doc(hidden)]
#[derive(Debug)]
Expand All @@ -25,7 +26,9 @@ pub struct MicroSecondsTimestampVisitor;
#[derive(Debug)]
pub struct MilliSecondsTimestampVisitor;

/// Serialize into a rfc3339 time string
/// Serialize into a rfc3339 time string.
/// In addition to rfc3339 the offset may contain seconds when present, instead of only hours and
/// minutes.
///
/// See [the `serde` module](./serde/index.html) for alternate
/// serializations.
Expand All @@ -34,18 +37,25 @@ impl<Tz: TimeZone> ser::Serialize for DateTime<Tz> {
where
S: ser::Serializer,
{
struct FormatWrapped<'a, D: 'a> {
inner: &'a D,
struct DisplayModifiedRfc3339<'a, Tz: TimeZone> {
inner: &'a DateTime<Tz>,
}

impl<'a, D: fmt::Debug> fmt::Display for FormatWrapped<'a, D> {
impl<'a, Tz: TimeZone> fmt::Display for DisplayModifiedRfc3339<'a, Tz> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.inner.fmt(f)
// Reuse `Debug` impls, which is faster.
Debug::fmt(&self.inner.naive_local(), f)?;
let offset = (*self.inner.offset()).fix();
// Choose a more compact representation (`Z`) for UTC datetimes.
if Some(offset) == FixedOffset::east_opt(0) {
f.write_char('Z')
} else {
Debug::fmt(&offset, f)
}
}
}

// Debug formatting is correct RFC3339, and it allows Zulu.
serializer.collect_str(&FormatWrapped { inner: &self })
serializer.collect_str(&DisplayModifiedRfc3339 { inner: &self })
}
}

Expand Down

0 comments on commit e160979

Please sign in to comment.