-
Notifications
You must be signed in to change notification settings - Fork 533
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Serde rfc 2822 #1412
Serde rfc 2822 #1412
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,10 @@ | |
#[derive(Debug)] | ||
pub struct MilliSecondsTimestampVisitor; | ||
|
||
#[doc(hidden)] | ||
#[derive(Debug)] | ||
pub struct Rfc2822Visitor; | ||
|
||
/// Serialize into an ISO 8601 formatted string. | ||
/// | ||
/// See [the `serde` module](./serde/index.html) for alternate | ||
|
@@ -1168,6 +1172,77 @@ | |
} | ||
} | ||
|
||
/// Ser/de to/from RFC 2822 strings | ||
/// | ||
/// Intended for use with `serde`'s `with` attribute. | ||
/// | ||
/// # Example: | ||
/// | ||
/// ```rust | ||
/// use chrono::{DateTime, NaiveDate, FixedOffset, TimeZone}; | ||
/// use serde_derive::{Deserialize, Serialize}; | ||
/// | ||
/// #[derive(Deserialize, Serialize)] | ||
/// struct Example { | ||
/// #[serde(with = "chrono::serde::rfc2822")] | ||
/// time: DateTime<FixedOffset> | ||
/// } | ||
/// let offset = 3600; | ||
/// let actual_time = NaiveDate::from_ymd_opt(2018, 5, 17).unwrap() | ||
/// .and_hms_opt(02, 04, 59).unwrap() | ||
/// .and_local_timezone(TimeZone::from_offset(&FixedOffset::east_opt(offset).unwrap())).unwrap(); | ||
/// let to_serialize = Example { | ||
/// time: actual_time.clone(), | ||
/// }; | ||
/// | ||
/// let serialized = serde_json::to_string(&to_serialize).unwrap(); | ||
/// assert_eq!(serialized, r#"{"time":"Thu, 17 May 2018 02:04:59 +0100"}"#); | ||
/// | ||
/// let deserialized: Example = serde_json::from_str(&serialized).unwrap(); | ||
/// assert_eq!(deserialized.time, actual_time); | ||
/// ``` | ||
pub mod rfc2822 { | ||
use crate::serde::Rfc2822Visitor; | ||
use crate::{DateTime, FixedOffset}; | ||
use core::fmt; | ||
use serde::{de, ser}; | ||
|
||
/// Serialize a datetime into an RFC 2822 formatted string, e.g. "01 Jun 2016 14:31:46 -0700" | ||
/// | ||
/// Intended for use with `serde`s `serialize_with` attribute. | ||
pub fn serialize<S>(dt: &DateTime<FixedOffset>, serializer: S) -> Result<S::Ok, S::Error> | ||
where | ||
S: ser::Serializer, | ||
{ | ||
serializer.serialize_str(&dt.to_rfc2822()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In You will have to adjust its |
||
} | ||
|
||
/// Deserialize a [`DateTime`] from an RFC 2822 datetime | ||
/// | ||
/// Intended for use with `serde`s `deserialize_with` attribute. | ||
pub fn deserialize<'de, D>(deserializer: D) -> Result<DateTime<FixedOffset>, D::Error> | ||
where | ||
D: de::Deserializer<'de>, | ||
{ | ||
deserializer.deserialize_str(Rfc2822Visitor) | ||
} | ||
|
||
impl<'de> de::Visitor<'de> for Rfc2822Visitor { | ||
type Value = DateTime<FixedOffset>; | ||
|
||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { | ||
formatter.write_str("an RFC 2822 (email) formatted datetime string") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Personally I would remove |
||
} | ||
|
||
fn visit_str<E>(self, date_string: &str) -> Result<Self::Value, E> | ||
where | ||
E: de::Error, | ||
{ | ||
DateTime::parse_from_rfc2822(date_string).map_err(E::custom) | ||
} | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
#[cfg(feature = "clock")] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe you can make this private. The others are public for backwards compatibility.