mirror of
				https://github.com/chronotope/chrono.git
				synced 2025-11-03 23:13:24 +00:00 
			
		
		
		
	Merge pull request #533 from nickelc/datetime-serde-micro-opt
This commit is contained in:
		
						commit
						7a357cdaca
					
				
							
								
								
									
										164
									
								
								src/datetime.rs
									
									
									
									
									
								
							
							
						
						
									
										164
									
								
								src/datetime.rs
									
									
									
									
									
								
							@ -1195,6 +1195,10 @@ pub mod serde {
 | 
				
			|||||||
    #[derive(Debug)]
 | 
					    #[derive(Debug)]
 | 
				
			||||||
    pub struct NanoSecondsTimestampVisitor;
 | 
					    pub struct NanoSecondsTimestampVisitor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[doc(hidden)]
 | 
				
			||||||
 | 
					    #[derive(Debug)]
 | 
				
			||||||
 | 
					    pub struct MicroSecondsTimestampVisitor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[doc(hidden)]
 | 
					    #[doc(hidden)]
 | 
				
			||||||
    #[derive(Debug)]
 | 
					    #[derive(Debug)]
 | 
				
			||||||
    pub struct MilliSecondsTimestampVisitor;
 | 
					    pub struct MilliSecondsTimestampVisitor;
 | 
				
			||||||
@ -1412,7 +1416,7 @@ pub mod serde {
 | 
				
			|||||||
        use offset::TimeZone;
 | 
					        use offset::TimeZone;
 | 
				
			||||||
        use {DateTime, Utc};
 | 
					        use {DateTime, Utc};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        use super::serde_from;
 | 
					        use super::{serde_from, MicroSecondsTimestampVisitor};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /// Serialize a UTC datetime into an integer number of microseconds since the epoch
 | 
					        /// Serialize a UTC datetime into an integer number of microseconds since the epoch
 | 
				
			||||||
        ///
 | 
					        ///
 | 
				
			||||||
@ -1488,8 +1492,6 @@ pub mod serde {
 | 
				
			|||||||
            Ok(d.deserialize_i64(MicroSecondsTimestampVisitor)?)
 | 
					            Ok(d.deserialize_i64(MicroSecondsTimestampVisitor)?)
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        struct MicroSecondsTimestampVisitor;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        impl<'de> de::Visitor<'de> for MicroSecondsTimestampVisitor {
 | 
					        impl<'de> de::Visitor<'de> for MicroSecondsTimestampVisitor {
 | 
				
			||||||
            type Value = DateTime<Utc>;
 | 
					            type Value = DateTime<Utc>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1524,6 +1526,162 @@ pub mod serde {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Ser/de to/from optional timestamps in microseconds
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// Intended for use with `serde`'s `with` attribute.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// # Example:
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// ```rust
 | 
				
			||||||
 | 
					    /// # // We mark this ignored so that we can test on 1.13 (which does not
 | 
				
			||||||
 | 
					    /// # // support custom derive), and run tests with --ignored on beta and
 | 
				
			||||||
 | 
					    /// # // nightly to actually trigger these.
 | 
				
			||||||
 | 
					    /// #
 | 
				
			||||||
 | 
					    /// # #[macro_use] extern crate serde_derive;
 | 
				
			||||||
 | 
					    /// # #[macro_use] extern crate serde_json;
 | 
				
			||||||
 | 
					    /// # extern crate chrono;
 | 
				
			||||||
 | 
					    /// # use chrono::{TimeZone, DateTime, Utc};
 | 
				
			||||||
 | 
					    /// use chrono::serde::ts_microseconds_option;
 | 
				
			||||||
 | 
					    /// #[derive(Deserialize, Serialize)]
 | 
				
			||||||
 | 
					    /// struct S {
 | 
				
			||||||
 | 
					    ///     #[serde(with = "ts_microseconds_option")]
 | 
				
			||||||
 | 
					    ///     time: Option<DateTime<Utc>>
 | 
				
			||||||
 | 
					    /// }
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// # fn example() -> Result<S, serde_json::Error> {
 | 
				
			||||||
 | 
					    /// let time = Some(Utc.ymd(2018, 5, 17).and_hms_micro(02, 04, 59, 918355));
 | 
				
			||||||
 | 
					    /// let my_s = S {
 | 
				
			||||||
 | 
					    ///     time: time.clone(),
 | 
				
			||||||
 | 
					    /// };
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// let as_string = serde_json::to_string(&my_s)?;
 | 
				
			||||||
 | 
					    /// assert_eq!(as_string, r#"{"time":1526522699918355}"#);
 | 
				
			||||||
 | 
					    /// let my_s: S = serde_json::from_str(&as_string)?;
 | 
				
			||||||
 | 
					    /// assert_eq!(my_s.time, time);
 | 
				
			||||||
 | 
					    /// # Ok(my_s)
 | 
				
			||||||
 | 
					    /// # }
 | 
				
			||||||
 | 
					    /// # fn main() { example().unwrap(); }
 | 
				
			||||||
 | 
					    /// ```
 | 
				
			||||||
 | 
					    pub mod ts_microseconds_option {
 | 
				
			||||||
 | 
					        use core::fmt;
 | 
				
			||||||
 | 
					        use serdelib::{de, ser};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        use {DateTime, Utc};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        use super::MicroSecondsTimestampVisitor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// Serialize a UTC datetime into an integer number of microseconds since the epoch or none
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// Intended for use with `serde`s `serialize_with` attribute.
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// # Example:
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// ```rust
 | 
				
			||||||
 | 
					        /// # // We mark this ignored so that we can test on 1.13 (which does not
 | 
				
			||||||
 | 
					        /// # // support custom derive), and run tests with --ignored on beta and
 | 
				
			||||||
 | 
					        /// # // nightly to actually trigger these.
 | 
				
			||||||
 | 
					        /// #
 | 
				
			||||||
 | 
					        /// # #[macro_use] extern crate serde_derive;
 | 
				
			||||||
 | 
					        /// # #[macro_use] extern crate serde_json;
 | 
				
			||||||
 | 
					        /// # extern crate chrono;
 | 
				
			||||||
 | 
					        /// # use chrono::{TimeZone, DateTime, Utc};
 | 
				
			||||||
 | 
					        /// use chrono::serde::ts_microseconds_option::serialize as to_micro_tsopt;
 | 
				
			||||||
 | 
					        /// #[derive(Serialize)]
 | 
				
			||||||
 | 
					        /// struct S {
 | 
				
			||||||
 | 
					        ///     #[serde(serialize_with = "to_micro_tsopt")]
 | 
				
			||||||
 | 
					        ///     time: Option<DateTime<Utc>>
 | 
				
			||||||
 | 
					        /// }
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// # fn example() -> Result<String, serde_json::Error> {
 | 
				
			||||||
 | 
					        /// let my_s = S {
 | 
				
			||||||
 | 
					        ///     time: Some(Utc.ymd(2018, 5, 17).and_hms_micro(02, 04, 59, 918355)),
 | 
				
			||||||
 | 
					        /// };
 | 
				
			||||||
 | 
					        /// let as_string = serde_json::to_string(&my_s)?;
 | 
				
			||||||
 | 
					        /// assert_eq!(as_string, r#"{"time":1526522699918355}"#);
 | 
				
			||||||
 | 
					        /// # Ok(as_string)
 | 
				
			||||||
 | 
					        /// # }
 | 
				
			||||||
 | 
					        /// # fn main() { example().unwrap(); }
 | 
				
			||||||
 | 
					        /// ```
 | 
				
			||||||
 | 
					        pub fn serialize<S>(opt: &Option<DateTime<Utc>>, serializer: S) -> Result<S::Ok, S::Error>
 | 
				
			||||||
 | 
					        where
 | 
				
			||||||
 | 
					            S: ser::Serializer,
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            match *opt {
 | 
				
			||||||
 | 
					                Some(ref dt) => serializer.serialize_some(&dt.timestamp_micros()),
 | 
				
			||||||
 | 
					                None => serializer.serialize_none(),
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// Deserialize a `DateTime` from a microsecond timestamp or none
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// Intended for use with `serde`s `deserialize_with` attribute.
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// # Example:
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// ```rust
 | 
				
			||||||
 | 
					        /// # // We mark this ignored so that we can test on 1.13 (which does not
 | 
				
			||||||
 | 
					        /// # // support custom derive), and run tests with --ignored on beta and
 | 
				
			||||||
 | 
					        /// # // nightly to actually trigger these.
 | 
				
			||||||
 | 
					        /// #
 | 
				
			||||||
 | 
					        /// # #[macro_use] extern crate serde_derive;
 | 
				
			||||||
 | 
					        /// # #[macro_use] extern crate serde_json;
 | 
				
			||||||
 | 
					        /// # extern crate chrono;
 | 
				
			||||||
 | 
					        /// # use chrono::{DateTime, Utc};
 | 
				
			||||||
 | 
					        /// use chrono::serde::ts_microseconds_option::deserialize as from_micro_tsopt;
 | 
				
			||||||
 | 
					        /// #[derive(Deserialize)]
 | 
				
			||||||
 | 
					        /// struct S {
 | 
				
			||||||
 | 
					        ///     #[serde(deserialize_with = "from_micro_tsopt")]
 | 
				
			||||||
 | 
					        ///     time: Option<DateTime<Utc>>
 | 
				
			||||||
 | 
					        /// }
 | 
				
			||||||
 | 
					        ///
 | 
				
			||||||
 | 
					        /// # fn example() -> Result<S, serde_json::Error> {
 | 
				
			||||||
 | 
					        /// let my_s: S = serde_json::from_str(r#"{ "time": 1526522699918355 }"#)?;
 | 
				
			||||||
 | 
					        /// # Ok(my_s)
 | 
				
			||||||
 | 
					        /// # }
 | 
				
			||||||
 | 
					        /// # fn main() { example().unwrap(); }
 | 
				
			||||||
 | 
					        /// ```
 | 
				
			||||||
 | 
					        pub fn deserialize<'de, D>(d: D) -> Result<Option<DateTime<Utc>>, D::Error>
 | 
				
			||||||
 | 
					        where
 | 
				
			||||||
 | 
					            D: de::Deserializer<'de>,
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Ok(d.deserialize_option(OptionMicroSecondsTimestampVisitor)?)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        struct OptionMicroSecondsTimestampVisitor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        impl<'de> de::Visitor<'de> for OptionMicroSecondsTimestampVisitor {
 | 
				
			||||||
 | 
					            type Value = Option<DateTime<Utc>>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
 | 
				
			||||||
 | 
					                write!(formatter, "a unix timestamp in microseconds or none")
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /// Deserialize a timestamp in seconds since the epoch
 | 
				
			||||||
 | 
					            fn visit_some<D>(self, d: D) -> Result<Option<DateTime<Utc>>, D::Error>
 | 
				
			||||||
 | 
					            where
 | 
				
			||||||
 | 
					                D: de::Deserializer<'de>,
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                d.deserialize_i64(MicroSecondsTimestampVisitor).map(Some)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /// Deserialize a timestamp in seconds since the epoch
 | 
				
			||||||
 | 
					            fn visit_none<E>(self) -> Result<Option<DateTime<Utc>>, E>
 | 
				
			||||||
 | 
					            where
 | 
				
			||||||
 | 
					                E: de::Error,
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Ok(None)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            /// Deserialize a timestamp in seconds since the epoch
 | 
				
			||||||
 | 
					            fn visit_unit<E>(self) -> Result<Option<DateTime<Utc>>, E>
 | 
				
			||||||
 | 
					            where
 | 
				
			||||||
 | 
					                E: de::Error,
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Ok(None)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Ser/de to/from timestamps in nanoseconds
 | 
					    /// Ser/de to/from timestamps in nanoseconds
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// Intended for use with `serde`'s `with` attribute.
 | 
					    /// Intended for use with `serde`'s `with` attribute.
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user