diff --git a/ifc/src/lib.rs b/ifc/src/lib.rs index 30db983..d3b1417 100644 --- a/ifc/src/lib.rs +++ b/ifc/src/lib.rs @@ -12,6 +12,7 @@ You should have received a copy of the GNU General Public License along with Lum use chrono::{Datelike, NaiveDate}; use serde::{Deserialize, Serialize}; +use std::convert::TryInto; use thiserror::Error; #[derive(Clone, Debug, Error, PartialEq)] @@ -206,9 +207,27 @@ pub struct Day { day: u8, } -impl From for Day { +impl From for IFC { fn from(date: chrono::NaiveDate) -> Self { - unimplemented!(); + if date.month() == 12 && date.day() == 31 { + Self::YearDay(date.year()) + } else if is_leap_year(date.year()) && date.month() == 6 && date.day() == 17 { + Self::LeapDay(date.year()) + } else { + let mut days = date.ordinal(); + if is_leap_year(date.year()) + && date > NaiveDate::from_ymd_opt(date.year(), 6, 17).unwrap() + { + days = days - 1; + } + let month: u8 = (days / 28).try_into().unwrap(); + let day: u8 = (days % 28).try_into().unwrap(); + Self::Day(Day { + year: date.year(), + month: month + 1, + day, + }) + } } } @@ -586,6 +605,141 @@ mod tests { assert_eq!(IFC::ymd(12022, 13, 28).unwrap().week_ordinal0(), 51); } + #[test] + fn it_converts_from_gregorian() { + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12022, 1, 1).unwrap()), + IFC::ymd(12022, 1, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12022, 1, 29).unwrap()), + IFC::ymd(12022, 2, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12022, 2, 26).unwrap()), + IFC::ymd(12022, 3, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12022, 3, 26).unwrap()), + IFC::ymd(12022, 4, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12022, 4, 23).unwrap()), + IFC::ymd(12022, 5, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12022, 5, 21).unwrap()), + IFC::ymd(12022, 6, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12022, 6, 18).unwrap()), + IFC::ymd(12022, 7, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12022, 7, 16).unwrap()), + IFC::ymd(12022, 8, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12022, 8, 13).unwrap()), + IFC::ymd(12022, 9, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12022, 9, 10).unwrap()), + IFC::ymd(12022, 10, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12022, 10, 8).unwrap()), + IFC::ymd(12022, 11, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12022, 11, 5).unwrap()), + IFC::ymd(12022, 12, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12022, 12, 3).unwrap()), + IFC::ymd(12022, 13, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12022, 12, 31).unwrap()), + IFC::YearDay(12022) + ); + } + + #[test] + fn it_converts_from_gregorian_on_leap_year() { + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12020, 1, 1).unwrap()), + IFC::ymd(12020, 1, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12020, 1, 29).unwrap()), + IFC::ymd(12020, 2, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12020, 2, 26).unwrap()), + IFC::ymd(12020, 3, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12020, 2, 28).unwrap()), + IFC::ymd(12020, 3, 3).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12020, 2, 29).unwrap()), + IFC::ymd(12020, 3, 4).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12020, 3, 1).unwrap()), + IFC::ymd(12020, 3, 5).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12020, 3, 25).unwrap()), + IFC::ymd(12020, 4, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12020, 4, 22).unwrap()), + IFC::ymd(12020, 5, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12020, 5, 20).unwrap()), + IFC::ymd(12020, 6, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12020, 6, 17).unwrap()), + IFC::LeapDay(12020) + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12020, 6, 18).unwrap()), + IFC::ymd(12020, 7, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12020, 7, 16).unwrap()), + IFC::ymd(12020, 8, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12020, 8, 13).unwrap()), + IFC::ymd(12020, 9, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12020, 9, 10).unwrap()), + IFC::ymd(12020, 10, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12020, 10, 8).unwrap()), + IFC::ymd(12020, 11, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12020, 11, 5).unwrap()), + IFC::ymd(12020, 12, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12020, 12, 3).unwrap()), + IFC::ymd(12020, 13, 1).unwrap() + ); + assert_eq!( + IFC::from(NaiveDate::from_ymd_opt(12020, 12, 31).unwrap()), + IFC::YearDay(12020) + ); + } /* #[test] fn check_start_of_month() {