diff options
Diffstat (limited to 'src/types.rs')
-rw-r--r-- | src/types.rs | 91 |
1 files changed, 63 insertions, 28 deletions
diff --git a/src/types.rs b/src/types.rs index b65fad4..ad3a570 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,13 +1,16 @@ //! Types that specify what is contained in a ZIP. -#[cfg(doc)] -use {crate::read::ZipFile, crate::write::FileOptions}; - +#[cfg(feature = "time")] +use std::convert::{TryFrom, TryInto}; #[cfg(not(any( all(target_arch = "arm", target_pointer_width = "32"), target_arch = "mips", target_arch = "powerpc" )))] use std::sync::atomic; +#[cfg(not(feature = "time"))] +use std::time::SystemTime; +#[cfg(doc)] +use {crate::read::ZipFile, crate::write::FileOptions}; #[cfg(any( all(target_arch = "arm", target_pointer_width = "32"), @@ -42,9 +45,11 @@ mod atomic { } #[cfg(feature = "time")] +use crate::result::DateTimeRangeError; +#[cfg(feature = "time")] use time::{error::ComponentRange, Date, Month, OffsetDateTime, PrimitiveDateTime, Time}; -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum System { Dos = 0, Unix = 3, @@ -115,7 +120,7 @@ impl DateTime { let years = (datepart & 0b1111111000000000) >> 9; DateTime { - year: (years + 1980) as u16, + year: years + 1980, month: months as u8, day: days as u8, hour: hours as u8, @@ -143,10 +148,8 @@ impl DateTime { second: u8, ) -> Result<DateTime, ()> { if (1980..=2107).contains(&year) - && month >= 1 - && month <= 12 - && day >= 1 - && day <= 31 + && (1..=12).contains(&month) + && (1..=31).contains(&day) && hour <= 23 && minute <= 59 && second <= 60 @@ -169,19 +172,9 @@ impl DateTime { /// /// Returns `Err` when this object is out of bounds #[allow(clippy::result_unit_err)] + #[deprecated(note = "use `DateTime::try_from()`")] pub fn from_time(dt: OffsetDateTime) -> Result<DateTime, ()> { - if dt.year() >= 1980 && dt.year() <= 2107 { - Ok(DateTime { - year: (dt.year()) as u16, - month: (dt.month()) as u8, - day: dt.day() as u8, - hour: dt.hour() as u8, - minute: dt.minute() as u8, - second: dt.second() as u8, - }) - } else { - Err(()) - } + dt.try_into().map_err(|_err| ()) } /// Gets the time portion of this datetime in the msdos representation @@ -197,8 +190,6 @@ impl DateTime { #[cfg(feature = "time")] /// Converts the DateTime to a OffsetDateTime structure pub fn to_time(&self) -> Result<OffsetDateTime, ComponentRange> { - use std::convert::TryFrom; - let date = Date::from_calendar_date(self.year as i32, Month::try_from(self.month)?, self.day)?; let time = Time::from_hms(self.hour, self.minute, self.second)?; @@ -256,6 +247,26 @@ impl DateTime { } } +#[cfg(feature = "time")] +impl TryFrom<OffsetDateTime> for DateTime { + type Error = DateTimeRangeError; + + fn try_from(dt: OffsetDateTime) -> Result<Self, Self::Error> { + if dt.year() >= 1980 && dt.year() <= 2107 { + Ok(DateTime { + year: (dt.year()) as u16, + month: (dt.month()) as u8, + day: dt.day(), + hour: dt.hour(), + minute: dt.minute(), + second: dt.second(), + }) + } else { + Err(DateTimeRangeError) + } + } +} + pub const DEFAULT_VERSION: u8 = 46; /// A type like `AtomicU64` except it implements `Clone` and has predefined @@ -500,20 +511,43 @@ mod test { #[cfg(feature = "time")] #[test] fn datetime_from_time_bounds() { + use std::convert::TryFrom; + + use super::DateTime; + use time::macros::datetime; + + // 1979-12-31 23:59:59 + assert!(DateTime::try_from(datetime!(1979-12-31 23:59:59 UTC)).is_err()); + + // 1980-01-01 00:00:00 + assert!(DateTime::try_from(datetime!(1980-01-01 00:00:00 UTC)).is_ok()); + + // 2107-12-31 23:59:59 + assert!(DateTime::try_from(datetime!(2107-12-31 23:59:59 UTC)).is_ok()); + + // 2108-01-01 00:00:00 + assert!(DateTime::try_from(datetime!(2108-01-01 00:00:00 UTC)).is_err()); + } + + #[cfg(feature = "time")] + #[test] + fn datetime_try_from_bounds() { + use std::convert::TryFrom; + use super::DateTime; use time::macros::datetime; // 1979-12-31 23:59:59 - assert!(DateTime::from_time(datetime!(1979-12-31 23:59:59 UTC)).is_err()); + assert!(DateTime::try_from(datetime!(1979-12-31 23:59:59 UTC)).is_err()); // 1980-01-01 00:00:00 - assert!(DateTime::from_time(datetime!(1980-01-01 00:00:00 UTC)).is_ok()); + assert!(DateTime::try_from(datetime!(1980-01-01 00:00:00 UTC)).is_ok()); // 2107-12-31 23:59:59 - assert!(DateTime::from_time(datetime!(2107-12-31 23:59:59 UTC)).is_ok()); + assert!(DateTime::try_from(datetime!(2107-12-31 23:59:59 UTC)).is_ok()); // 2108-01-01 00:00:00 - assert!(DateTime::from_time(datetime!(2108-01-01 00:00:00 UTC)).is_err()); + assert!(DateTime::try_from(datetime!(2108-01-01 00:00:00 UTC)).is_err()); } #[test] @@ -564,10 +598,11 @@ mod test { #[test] fn time_at_january() { use super::DateTime; + use std::convert::TryFrom; // 2020-01-01 00:00:00 let clock = OffsetDateTime::from_unix_timestamp(1_577_836_800).unwrap(); - assert!(DateTime::from_time(clock).is_ok()); + assert!(DateTime::try_from(clock).is_ok()); } } |