diff --git a/src/date.rs b/src/date.rs index 35dc17c..55d9b24 100644 --- a/src/date.rs +++ b/src/date.rs @@ -1,6 +1,7 @@ use std::fmt; /// Release date including year, month, and day. +// Internal storage is: y[31..9] | m[8..5] | d[5...0]. #[derive(Debug, PartialEq, Eq, Copy, Clone, PartialOrd, Ord)] pub struct Date(u32); @@ -25,11 +26,11 @@ impl Date { } /// Return the original (YYYY, MM, DD). - fn to_ymd(&self) -> (u8, u8, u8) { + fn to_ymd(&self) -> (u16, u8, u8) { let y = self.0 >> 9; let m = (self.0 << 23) >> 28; let d = (self.0 << 27) >> 27; - (y as u8, m as u8, d as u8) + (y as u16, m as u8, d as u8) } /// Parse a release date of the form `%Y-%m-%d`. Returns `None` if `date` is @@ -59,7 +60,7 @@ impl Date { } let (y, m, d) = (ymd[0], ymd[1], ymd[2]); - Some(Date((y << 9) | (m << 5) | d)) + Some(Date((y << 9) | ((m & 0xF) << 5) | (d & 0x1F))) } /// Returns `true` if `self` occurs on or after `date`. @@ -141,6 +142,26 @@ impl Date { impl fmt::Display for Date { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let (y, m, d) = self.to_ymd(); - write!(f, "{}-{}-{}", y, m, d) + write!(f, "{}-{:02}-{:02}", y, m, d) + } +} + +#[cfg(test)] +mod tests { + use super::Date; + + macro_rules! reflexive_display { + ($string:expr) => ( + assert_eq!(Date::parse($string).unwrap().to_string(), $string); + ) + } + + #[test] + fn display() { + reflexive_display!("2019-05-08"); + reflexive_display!("2000-01-01"); + reflexive_display!("2000-12-31"); + reflexive_display!("2090-12-31"); + reflexive_display!("1999-02-19"); } } diff --git a/src/version.rs b/src/version.rs index 911545e..a0738d9 100644 --- a/src/version.rs +++ b/src/version.rs @@ -194,6 +194,8 @@ mod tests { let version = Version::parse("1.18.0").unwrap(); assert!(version.exactly("1.18.0")); assert!(version.at_least("1.12.0")); + assert!(version.at_least("1.12")); + assert!(version.at_least("1")); assert!(version.at_most("1.18.1")); assert!(!version.exactly("1.19.0")); assert!(!version.exactly("1.18.1")); @@ -218,4 +220,19 @@ mod tests { assert!(Version::parse("one.two.three").is_none()); } + macro_rules! reflexive_display { + ($s:expr) => ( + assert_eq!(Version::parse($s).unwrap().to_string(), $s); + ) + } + + #[test] + fn display() { + reflexive_display!("1.0.0"); + reflexive_display!("1.2.3"); + reflexive_display!("1.12.1438"); + reflexive_display!("1.44.0"); + reflexive_display!("2.44.0"); + reflexive_display!("23459.28923.3483"); + } }