@@ -1168,6 +1168,92 @@ pub mod ts_seconds_option {
1168
1168
}
1169
1169
}
1170
1170
1171
+ /// Ser/de to/from RFC 2822 strings
1172
+ ///
1173
+ /// Intended for use with `serde`'s `with` attribute.
1174
+ ///
1175
+ /// # Example:
1176
+ ///
1177
+ /// ```rust
1178
+ /// use chrono::{DateTime, NaiveDate, FixedOffset, TimeZone};
1179
+ /// use serde_derive::{Deserialize, Serialize};
1180
+ ///
1181
+ /// #[derive(Deserialize, Serialize)]
1182
+ /// struct Example {
1183
+ /// #[serde(with = "chrono::serde::rfc2822")]
1184
+ /// time: DateTime<FixedOffset>
1185
+ /// }
1186
+ /// let offset = 3600;
1187
+ /// let actual_time = NaiveDate::from_ymd_opt(2018, 5, 17).unwrap()
1188
+ /// .and_hms_opt(02, 04, 59).unwrap()
1189
+ /// .and_local_timezone(TimeZone::from_offset(&FixedOffset::east_opt(offset).unwrap())).unwrap();
1190
+ /// let to_serialize = Example {
1191
+ /// time: actual_time.clone(),
1192
+ /// };
1193
+ ///
1194
+ /// let serialized = serde_json::to_string(&to_serialize).unwrap();
1195
+ /// assert_eq!(serialized, r#"{"time":"Thu, 17 May 2018 02:04:59 +0100"}"#);
1196
+ ///
1197
+ /// let deserialized: Example = serde_json::from_str(&serialized).unwrap();
1198
+ /// assert_eq!(deserialized.time, actual_time);
1199
+ /// ```
1200
+ pub mod rfc2822 {
1201
+ use crate :: { DateTime , FixedOffset , Offset , TimeZone } ;
1202
+ use crate :: format:: write_rfc2822;
1203
+ use core:: fmt;
1204
+ use serde:: { de, ser} ;
1205
+
1206
+ /// Serialize a datetime into an RFC 2822 formatted string, e.g. "01 Jun 2016 14:31:46 -0700"
1207
+ ///
1208
+ /// Intended for use with `serde`s `serialize_with` attribute.
1209
+ pub fn serialize < S > ( dt : & DateTime < FixedOffset > , serializer : S ) -> Result < S :: Ok , S :: Error >
1210
+ where
1211
+ S : ser:: Serializer ,
1212
+ {
1213
+ struct FormatRfc2822 < ' a , Tz : TimeZone > {
1214
+ inner : & ' a DateTime < Tz > ,
1215
+ }
1216
+
1217
+ impl < ' a , Tz : TimeZone > fmt:: Display for FormatRfc2822 < ' a , Tz > {
1218
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1219
+ let naive = self . inner . naive_local ( ) ;
1220
+ let offset = self . inner . offset . fix ( ) ;
1221
+ write_rfc2822 ( f, naive, offset)
1222
+ }
1223
+ }
1224
+
1225
+ serializer. collect_str ( & FormatRfc2822 { inner : dt } )
1226
+ }
1227
+
1228
+ #[ derive( Debug ) ]
1229
+ struct Rfc2822Visitor ;
1230
+
1231
+ /// Deserialize a [`DateTime`] from an RFC 2822 datetime
1232
+ ///
1233
+ /// Intended for use with `serde`s `deserialize_with` attribute.
1234
+ pub fn deserialize < ' de , D > ( deserializer : D ) -> Result < DateTime < FixedOffset > , D :: Error >
1235
+ where
1236
+ D : de:: Deserializer < ' de > ,
1237
+ {
1238
+ deserializer. deserialize_str ( Rfc2822Visitor )
1239
+ }
1240
+
1241
+ impl < ' de > de:: Visitor < ' de > for Rfc2822Visitor {
1242
+ type Value = DateTime < FixedOffset > ;
1243
+
1244
+ fn expecting ( & self , formatter : & mut fmt:: Formatter ) -> fmt:: Result {
1245
+ formatter. write_str ( "an RFC 2822 formatted datetime string" )
1246
+ }
1247
+
1248
+ fn visit_str < E > ( self , date_string : & str ) -> Result < Self :: Value , E >
1249
+ where
1250
+ E : de:: Error ,
1251
+ {
1252
+ DateTime :: parse_from_rfc2822 ( date_string) . map_err ( E :: custom)
1253
+ }
1254
+ }
1255
+ }
1256
+
1171
1257
#[ cfg( test) ]
1172
1258
mod tests {
1173
1259
#[ cfg( feature = "clock" ) ]
0 commit comments