use chrono; use soft_ascii_string::SoftAsciiString; use internals::encoder::{EncodingWriter, EncodableInHeader}; use internals::error::EncodingError; use ::HeaderTryFrom; use ::error::ComponentCreationError; #[cfg(feature="serde")] use serde::{Serialize, Deserialize}; /// A DateTime header component wrapping chrono::DateTime #[derive(Debug, Clone, Hash, Eq, PartialEq)] #[cfg_attr(feature="serde", derive(Serialize, Deserialize))] pub struct DateTime( #[cfg_attr(feature="serde", serde(with = "super::utils::serde::date_time"))] chrono::DateTime ); impl DateTime { /// create a new DateTime of the current Time pub fn now() -> DateTime { DateTime( chrono::Utc::now() ) } /// create a new DateTime from a `chrono::DateTime` for any `TimeZone` pub fn new( date_time: chrono::DateTime) -> DateTime { DateTime( date_time.with_timezone( &chrono::Utc ) ) } #[doc(hidden)] #[cfg(test)] pub fn test_time( modif: u32 ) -> Self { use chrono::prelude::*; Self::new( FixedOffset::east( 3 * 3600 ).ymd( 2013, 8, 6 ).and_hms( 7, 11, modif ) ) } } impl EncodableInHeader for DateTime { fn encode(&self, handle: &mut EncodingWriter) -> Result<(), EncodingError> { let time = SoftAsciiString::from_unchecked(self.to_rfc2822()); handle.write_str( &*time )?; Ok( () ) } fn boxed_clone(&self) -> Box { Box::new(self.clone()) } } impl HeaderTryFrom> for DateTime where TZ: chrono::TimeZone { fn try_from(val: chrono::DateTime) -> Result { Ok(Self::new(val)) } } impl From> for DateTime where TZ: chrono::TimeZone { fn from(val: chrono::DateTime) -> Self { Self::new(val) } } impl Into> for DateTime { fn into(self) -> chrono::DateTime { self.0 } } deref0!{-mut DateTime => chrono::DateTime } #[cfg(test)] mod test { use super::DateTime; ec_test!{ date_time, { DateTime::test_time( 45 ) } => ascii => [ Text "Tue, 6 Aug 2013 04:11:45 +0000" ]} }