@@ -266,6 +266,8 @@ const OL_TO_MDL: &[u8; MAX_OL as usize + 1] = &[
266266///
267267/// The whole bits except for the least 3 bits are referred as `Ol` (ordinal and leap flag),
268268/// which is an index to the `OL_TO_MDL` lookup table.
269+ ///
270+ /// The methods implemented on `Of` always return a valid value.
269271#[ derive( PartialEq , PartialOrd , Copy , Clone ) ]
270272pub ( super ) struct Of ( u32 ) ;
271273
@@ -384,13 +386,17 @@ impl fmt::Debug for Of {
384386/// The whole bits except for the least 3 bits are referred as `Mdl`
385387/// (month, day of month and leap flag),
386388/// which is an index to the `MDL_TO_OL` lookup table.
389+ ///
390+ /// The methods implemented on `Mdf` do not always return a valid value.
391+ /// Dates than can't exist, like February 30, can still be represented.
392+ /// Use `Mdl::valid` to check whether the date is valid.
387393#[ derive( PartialEq , PartialOrd , Copy , Clone ) ]
388394pub ( super ) struct Mdf ( u32 ) ;
389395
390396impl Mdf {
391397 #[ inline]
392398 pub ( super ) const fn new ( month : u32 , day : u32 , YearFlags ( flags) : YearFlags ) -> Option < Mdf > {
393- match month <= 12 && day <= 31 {
399+ match month >= 1 && month <= 12 && day >= 1 && day <= 31 {
394400 true => Some ( Mdf ( ( month << 9 ) | ( day << 4 ) | flags as u32 ) ) ,
395401 false => None ,
396402 }
@@ -829,4 +835,33 @@ mod tests {
829835 }
830836 }
831837 }
838+
839+ #[ test]
840+ fn test_invalid_returns_none ( ) {
841+ let regular_year = YearFlags :: from_year ( 2023 ) ;
842+ let leap_year = YearFlags :: from_year ( 2024 ) ;
843+ assert ! ( Of :: new( 0 , regular_year) . is_none( ) ) ;
844+ assert ! ( Of :: new( 366 , regular_year) . is_none( ) ) ;
845+ assert ! ( Of :: new( 366 , leap_year) . is_some( ) ) ;
846+ assert ! ( Of :: new( 367 , regular_year) . is_none( ) ) ;
847+
848+ assert ! ( Mdf :: new( 0 , 1 , regular_year) . is_none( ) ) ;
849+ assert ! ( Mdf :: new( 13 , 1 , regular_year) . is_none( ) ) ;
850+ assert ! ( Mdf :: new( 1 , 0 , regular_year) . is_none( ) ) ;
851+ assert ! ( Mdf :: new( 1 , 32 , regular_year) . is_none( ) ) ;
852+ assert ! ( Mdf :: new( 2 , 31 , regular_year) . is_some( ) ) ;
853+
854+ assert ! ( Of :: from_mdf( Mdf :: new( 2 , 30 , regular_year) . unwrap( ) ) . is_none( ) ) ;
855+ assert ! ( Of :: from_mdf( Mdf :: new( 2 , 30 , leap_year) . unwrap( ) ) . is_none( ) ) ;
856+ assert ! ( Of :: from_mdf( Mdf :: new( 2 , 29 , regular_year) . unwrap( ) ) . is_none( ) ) ;
857+ assert ! ( Of :: from_mdf( Mdf :: new( 2 , 29 , leap_year) . unwrap( ) ) . is_some( ) ) ;
858+ assert ! ( Of :: from_mdf( Mdf :: new( 2 , 28 , regular_year) . unwrap( ) ) . is_some( ) ) ;
859+
860+ assert ! ( Of :: new( 365 , regular_year) . unwrap( ) . succ( ) . is_none( ) ) ;
861+ assert ! ( Of :: new( 365 , leap_year) . unwrap( ) . succ( ) . is_some( ) ) ;
862+ assert ! ( Of :: new( 366 , leap_year) . unwrap( ) . succ( ) . is_none( ) ) ;
863+
864+ assert ! ( Of :: new( 1 , regular_year) . unwrap( ) . pred( ) . is_none( ) ) ;
865+ assert ! ( Of :: new( 1 , leap_year) . unwrap( ) . pred( ) . is_none( ) ) ;
866+ }
832867}
0 commit comments