@@ -1213,6 +1213,92 @@ pub mod ts_seconds_option {
1213
1213
}
1214
1214
}
1215
1215
1216
+ /// Ser/de to/from RFC 2822 strings
1217
+ ///
1218
+ /// Intended for use with `serde`'s `with` attribute.
1219
+ ///
1220
+ /// # Example:
1221
+ ///
1222
+ /// ```rust
1223
+ /// use chrono::{DateTime, NaiveDate, FixedOffset, TimeZone};
1224
+ /// use serde_derive::{Deserialize, Serialize};
1225
+ ///
1226
+ /// #[derive(Deserialize, Serialize)]
1227
+ /// struct Example {
1228
+ /// #[serde(with = "chrono::serde::rfc2822")]
1229
+ /// time: DateTime<FixedOffset>
1230
+ /// }
1231
+ /// let offset = 3600;
1232
+ /// let actual_time = NaiveDate::from_ymd_opt(2018, 5, 17).unwrap()
1233
+ /// .and_hms_opt(02, 04, 59).unwrap()
1234
+ /// .and_local_timezone(TimeZone::from_offset(&FixedOffset::east_opt(offset).unwrap())).unwrap();
1235
+ /// let to_serialize = Example {
1236
+ /// time: actual_time.clone(),
1237
+ /// };
1238
+ ///
1239
+ /// let serialized = serde_json::to_string(&to_serialize).unwrap();
1240
+ /// assert_eq!(serialized, r#"{"time":"Thu, 17 May 2018 02:04:59 +0100"}"#);
1241
+ ///
1242
+ /// let deserialized: Example = serde_json::from_str(&serialized).unwrap();
1243
+ /// assert_eq!(deserialized.time, actual_time);
1244
+ /// ```
1245
+ pub mod rfc2822 {
1246
+ use crate :: { DateTime , FixedOffset , Offset , TimeZone } ;
1247
+ use crate :: format:: write_rfc2822;
1248
+ use core:: fmt;
1249
+ use serde:: { de, ser} ;
1250
+
1251
+ /// Serialize a datetime into an RFC 2822 formatted string, e.g. "01 Jun 2016 14:31:46 -0700"
1252
+ ///
1253
+ /// Intended for use with `serde`s `serialize_with` attribute.
1254
+ pub fn serialize < S > ( dt : & DateTime < FixedOffset > , serializer : S ) -> Result < S :: Ok , S :: Error >
1255
+ where
1256
+ S : ser:: Serializer ,
1257
+ {
1258
+ struct FormatRfc2822 < ' a , Tz : TimeZone > {
1259
+ inner : & ' a DateTime < Tz > ,
1260
+ }
1261
+
1262
+ impl < ' a , Tz : TimeZone > fmt:: Display for FormatRfc2822 < ' a , Tz > {
1263
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1264
+ let naive = self . inner . naive_local ( ) ;
1265
+ let offset = self . inner . offset . fix ( ) ;
1266
+ write_rfc2822 ( f, naive, offset)
1267
+ }
1268
+ }
1269
+
1270
+ serializer. collect_str ( & FormatRfc2822 { inner : dt } )
1271
+ }
1272
+
1273
+ #[ derive( Debug ) ]
1274
+ struct Rfc2822Visitor ;
1275
+
1276
+ /// Deserialize a [`DateTime`] from an RFC 2822 datetime
1277
+ ///
1278
+ /// Intended for use with `serde`s `deserialize_with` attribute.
1279
+ pub fn deserialize < ' de , D > ( deserializer : D ) -> Result < DateTime < FixedOffset > , D :: Error >
1280
+ where
1281
+ D : de:: Deserializer < ' de > ,
1282
+ {
1283
+ deserializer. deserialize_str ( Rfc2822Visitor )
1284
+ }
1285
+
1286
+ impl < ' de > de:: Visitor < ' de > for Rfc2822Visitor {
1287
+ type Value = DateTime < FixedOffset > ;
1288
+
1289
+ fn expecting ( & self , formatter : & mut fmt:: Formatter ) -> fmt:: Result {
1290
+ formatter. write_str ( "an RFC 2822 formatted datetime string" )
1291
+ }
1292
+
1293
+ fn visit_str < E > ( self , date_string : & str ) -> Result < Self :: Value , E >
1294
+ where
1295
+ E : de:: Error ,
1296
+ {
1297
+ DateTime :: parse_from_rfc2822 ( date_string) . map_err ( E :: custom)
1298
+ }
1299
+ }
1300
+ }
1301
+
1216
1302
#[ cfg( test) ]
1217
1303
mod tests {
1218
1304
#[ cfg( feature = "clock" ) ]
0 commit comments