mail_headers/header_components/
date_time.rs

1use chrono;
2use soft_ascii_string::SoftAsciiString;
3
4
5use internals::encoder::{EncodingWriter, EncodableInHeader};
6use internals::error::EncodingError;
7use ::HeaderTryFrom;
8use ::error::ComponentCreationError;
9
10#[cfg(feature="serde")]
11use serde::{Serialize, Deserialize};
12
13/// A DateTime header component wrapping chrono::DateTime<chrono::Utc>
14#[derive(Debug, Clone, Hash, Eq, PartialEq)]
15#[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
16pub struct DateTime(
17    #[cfg_attr(feature="serde", serde(with = "super::utils::serde::date_time"))]
18    chrono::DateTime<chrono::Utc>
19);
20
21impl DateTime {
22
23    /// create a new DateTime of the current Time
24    pub fn now() -> DateTime {
25        DateTime( chrono::Utc::now() )
26    }
27
28    /// create a new DateTime from a `chrono::DateTime<TimeZone>` for any `TimeZone`
29    pub fn new<TZ: chrono::TimeZone>( date_time: chrono::DateTime<TZ>) -> DateTime {
30        DateTime( date_time.with_timezone( &chrono::Utc ) )
31    }
32
33    #[doc(hidden)]
34    #[cfg(test)]
35    pub fn test_time( modif: u32 ) -> Self {
36        use chrono::prelude::*;
37        Self::new( FixedOffset::east( 3 * 3600 ).ymd( 2013, 8, 6 ).and_hms( 7, 11, modif ) )
38    }
39}
40
41impl EncodableInHeader for DateTime {
42
43    fn encode(&self, handle: &mut EncodingWriter) -> Result<(), EncodingError> {
44        let time = SoftAsciiString::from_unchecked(self.to_rfc2822());
45        handle.write_str( &*time )?;
46        Ok( () )
47    }
48
49    fn boxed_clone(&self) -> Box<EncodableInHeader> {
50        Box::new(self.clone())
51    }
52}
53
54
55impl<TZ> HeaderTryFrom<chrono::DateTime<TZ>> for DateTime
56    where TZ: chrono::TimeZone
57{
58    fn try_from(val: chrono::DateTime<TZ>) -> Result<Self, ComponentCreationError> {
59        Ok(Self::new(val))
60    }
61}
62
63impl<TZ> From<chrono::DateTime<TZ>> for DateTime
64    where TZ: chrono::TimeZone
65{
66    fn from(val: chrono::DateTime<TZ>) -> Self {
67        Self::new(val)
68    }
69}
70
71impl Into<chrono::DateTime<chrono::Utc>> for DateTime {
72    fn into(self) -> chrono::DateTime<chrono::Utc> {
73        self.0
74    }
75}
76
77deref0!{-mut DateTime => chrono::DateTime<chrono::Utc> }
78
79
80#[cfg(test)]
81mod test {
82    use super::DateTime;
83
84    ec_test!{ date_time, {
85        DateTime::test_time( 45 )
86    } => ascii => [
87        Text "Tue,  6 Aug 2013 04:11:45 +0000"
88    ]}
89
90}