From 1ef8a8505862191f21059f492069488e4f8a9ef1 Mon Sep 17 00:00:00 2001 From: Paul Dicker Date: Sun, 25 Feb 2024 21:28:07 +0100 Subject: [PATCH] Convert `NaiveDate::from_isoywd` to return `Result` --- src/format/parsed.rs | 4 ++-- src/lib.rs | 2 +- src/naive/date/mod.rs | 50 ++++++++++++++++++++++------------------- src/naive/date/tests.rs | 46 ++++++++++++++++++------------------- 4 files changed, 53 insertions(+), 49 deletions(-) diff --git a/src/format/parsed.rs b/src/format/parsed.rs index 8e393e28a4..6ce6968bae 100644 --- a/src/format/parsed.rs +++ b/src/format/parsed.rs @@ -470,8 +470,8 @@ impl Parsed { (_, Some(isoyear), &Parsed { isoweek: Some(isoweek), weekday: Some(weekday), .. }) => { // ISO year, week, day of the week - let date = NaiveDate::from_isoywd(isoyear, isoweek, weekday); - let date = date.ok_or(OUT_OF_RANGE)?; + let date = + NaiveDate::from_isoywd(isoyear, isoweek, weekday).map_err(|_| OUT_OF_RANGE)?; (verify_ymd(date) && verify_ordinal(date), date) } diff --git a/src/lib.rs b/src/lib.rs index fedf15ad55..75fd666e5a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -134,7 +134,7 @@ //! // July 8 is 188th day of the year 2014 (`o` for "ordinal") //! assert_eq!(dt, NaiveDate::from_yo(2014, 189).unwrap().and_hms(9, 10, 11).unwrap().and_utc()); //! // July 8 is Tuesday in ISO week 28 of the year 2014. -//! assert_eq!(dt, NaiveDate::from_isoywd(2014, 28, Weekday::Tue)?.and_hms(9, 10, 11).unwrap().and_utc()); +//! assert_eq!(dt, NaiveDate::from_isoywd(2014, 28, Weekday::Tue).unwrap().and_hms(9, 10, 11).unwrap().and_utc()); //! //! let dt = NaiveDate::from_ymd(2014, 7, 8).unwrap().and_hms_milli(9, 10, 11, 12).unwrap().and_local_timezone(Utc).unwrap(); // `2014-07-08T09:10:11.012Z` //! assert_eq!(dt, NaiveDate::from_ymd(2014, 7, 8).unwrap().and_hms_micro(9, 10, 11, 12_000).unwrap().and_local_timezone(Utc).unwrap()); diff --git a/src/naive/date/mod.rs b/src/naive/date/mod.rs index 1dd93551b6..09e224ad9f 100644 --- a/src/naive/date/mod.rs +++ b/src/naive/date/mod.rs @@ -216,55 +216,59 @@ impl NaiveDate { /// /// # Errors /// - /// Returns `None` if: - /// - The specified week does not exist in that year (for example 2023 week 53). - /// - The value for `week` is invalid (for example: `0`, `60`). - /// - If the resulting date is out of range for `NaiveDate`. + /// This method returns: + /// - [`Error::DoesNotExist`] if specified week does not exist in that year (for example 2023 + /// week 53). + /// - [`Error::InvalidArgument`] if the value for `week` is invalid (for example: `0`, `60`). + /// - [`Error::OutOfRange`] if the resulting date is out of range for `NaiveDate`. /// /// # Example /// /// ``` - /// use chrono::{NaiveDate, Weekday}; + /// use chrono::{Error, NaiveDate, Weekday}; /// /// let from_ymd = |y, m, d| NaiveDate::from_ymd(y, m, d).unwrap(); /// let from_isoywd = NaiveDate::from_isoywd; /// - /// assert_eq!(from_isoywd(2015, 0, Weekday::Sun), None); - /// assert_eq!(from_isoywd(2015, 10, Weekday::Sun), Some(from_ymd(2015, 3, 8))); - /// assert_eq!(from_isoywd(2015, 30, Weekday::Mon), Some(from_ymd(2015, 7, 20))); - /// assert_eq!(from_isoywd(2015, 60, Weekday::Mon), None); + /// assert_eq!(from_isoywd(2015, 0, Weekday::Sun), Err(Error::InvalidArgument)); + /// assert_eq!(from_isoywd(2015, 10, Weekday::Sun), Ok(from_ymd(2015, 3, 8))); + /// assert_eq!(from_isoywd(2015, 30, Weekday::Mon), Ok(from_ymd(2015, 7, 20))); + /// assert_eq!(from_isoywd(2015, 60, Weekday::Mon), Err(Error::InvalidArgument)); /// - /// assert_eq!(from_isoywd(400000, 10, Weekday::Fri), None); - /// assert_eq!(from_isoywd(-400000, 10, Weekday::Sat), None); + /// assert_eq!(from_isoywd(400000, 10, Weekday::Fri), Err(Error::OutOfRange)); + /// assert_eq!(from_isoywd(-400000, 10, Weekday::Sat), Err(Error::OutOfRange)); /// ``` /// /// The year number of ISO week date may differ from that of the calendar date. /// /// ``` - /// # use chrono::{NaiveDate, Weekday}; + /// # use chrono::{Error, NaiveDate, Weekday}; /// # let from_ymd = |y, m, d| NaiveDate::from_ymd(y, m, d).unwrap(); /// # let from_isoywd = NaiveDate::from_isoywd; /// // Mo Tu We Th Fr Sa Su /// // 2014-W52 22 23 24 25 26 27 28 has 4+ days of new year, /// // 2015-W01 29 30 31 1 2 3 4 <- so this is the first week - /// assert_eq!(from_isoywd(2014, 52, Weekday::Sun), Some(from_ymd(2014, 12, 28))); - /// assert_eq!(from_isoywd(2014, 53, Weekday::Mon), None); - /// assert_eq!(from_isoywd(2015, 1, Weekday::Mon), Some(from_ymd(2014, 12, 29))); + /// assert_eq!(from_isoywd(2014, 52, Weekday::Sun), Ok(from_ymd(2014, 12, 28))); + /// assert_eq!(from_isoywd(2014, 53, Weekday::Mon), Err(Error::DoesNotExist)); + /// assert_eq!(from_isoywd(2015, 1, Weekday::Mon), Ok(from_ymd(2014, 12, 29))); /// /// // 2015-W52 21 22 23 24 25 26 27 has 4+ days of old year, /// // 2015-W53 28 29 30 31 1 2 3 <- so this is the last week /// // 2016-W01 4 5 6 7 8 9 10 - /// assert_eq!(from_isoywd(2015, 52, Weekday::Sun), Some(from_ymd(2015, 12, 27))); - /// assert_eq!(from_isoywd(2015, 53, Weekday::Sun), Some(from_ymd(2016, 1, 3))); - /// assert_eq!(from_isoywd(2015, 54, Weekday::Mon), None); - /// assert_eq!(from_isoywd(2016, 1, Weekday::Mon), Some(from_ymd(2016, 1, 4))); + /// assert_eq!(from_isoywd(2015, 52, Weekday::Sun), Ok(from_ymd(2015, 12, 27))); + /// assert_eq!(from_isoywd(2015, 53, Weekday::Sun), Ok(from_ymd(2016, 1, 3))); + /// assert_eq!(from_isoywd(2015, 54, Weekday::Mon), Err(Error::InvalidArgument)); + /// assert_eq!(from_isoywd(2016, 1, Weekday::Mon), Ok(from_ymd(2016, 1, 4))); /// ``` - #[must_use] - pub const fn from_isoywd(year: i32, week: u32, weekday: Weekday) -> Option { + pub const fn from_isoywd(year: i32, week: u32, weekday: Weekday) -> Result { let flags = YearFlags::from_year(year); let nweeks = flags.nisoweeks(); if week == 0 || week > nweeks { - return None; + if week == 0 || week > 53 { + return Err(Error::InvalidArgument); + } else { + return Err(Error::DoesNotExist); + } } // ordinal = week ordinal - delta let weekord = week * 7 + weekday as u32; @@ -285,7 +289,7 @@ impl NaiveDate { (year + 1, ordinal - ndays, nextflags) } }; - ok!(NaiveDate::from_ordinal_and_flags(year, ordinal, flags)) + NaiveDate::from_ordinal_and_flags(year, ordinal, flags) } /// Makes a new `NaiveDate` from a day's number in the proleptic Gregorian calendar, with diff --git a/src/naive/date/tests.rs b/src/naive/date/tests.rs index ed8f5b14a9..79c8de267e 100644 --- a/src/naive/date/tests.rs +++ b/src/naive/date/tests.rs @@ -201,28 +201,28 @@ fn test_date_from_isoywd() { let from_isoywd = NaiveDate::from_isoywd; let ymd = |y, m, d| NaiveDate::from_ymd(y, m, d).unwrap(); - assert_eq!(from_isoywd(2004, 0, Weekday::Sun), None); - assert_eq!(from_isoywd(2004, 1, Weekday::Mon), Some(ymd(2003, 12, 29))); - assert_eq!(from_isoywd(2004, 1, Weekday::Sun), Some(ymd(2004, 1, 4))); - assert_eq!(from_isoywd(2004, 2, Weekday::Mon), Some(ymd(2004, 1, 5))); - assert_eq!(from_isoywd(2004, 2, Weekday::Sun), Some(ymd(2004, 1, 11))); - assert_eq!(from_isoywd(2004, 52, Weekday::Mon), Some(ymd(2004, 12, 20))); - assert_eq!(from_isoywd(2004, 52, Weekday::Sun), Some(ymd(2004, 12, 26))); - assert_eq!(from_isoywd(2004, 53, Weekday::Mon), Some(ymd(2004, 12, 27))); - assert_eq!(from_isoywd(2004, 53, Weekday::Sun), Some(ymd(2005, 1, 2))); - assert_eq!(from_isoywd(2004, 54, Weekday::Mon), None); - - assert_eq!(from_isoywd(2011, 0, Weekday::Sun), None); - assert_eq!(from_isoywd(2011, 1, Weekday::Mon), Some(ymd(2011, 1, 3))); - assert_eq!(from_isoywd(2011, 1, Weekday::Sun), Some(ymd(2011, 1, 9))); - assert_eq!(from_isoywd(2011, 2, Weekday::Mon), Some(ymd(2011, 1, 10))); - assert_eq!(from_isoywd(2011, 2, Weekday::Sun), Some(ymd(2011, 1, 16))); - - assert_eq!(from_isoywd(2018, 51, Weekday::Mon), Some(ymd(2018, 12, 17))); - assert_eq!(from_isoywd(2018, 51, Weekday::Sun), Some(ymd(2018, 12, 23))); - assert_eq!(from_isoywd(2018, 52, Weekday::Mon), Some(ymd(2018, 12, 24))); - assert_eq!(from_isoywd(2018, 52, Weekday::Sun), Some(ymd(2018, 12, 30))); - assert_eq!(from_isoywd(2018, 53, Weekday::Mon), None); + assert_eq!(from_isoywd(2004, 0, Weekday::Sun), Err(Error::InvalidArgument)); + assert_eq!(from_isoywd(2004, 1, Weekday::Mon), Ok(ymd(2003, 12, 29))); + assert_eq!(from_isoywd(2004, 1, Weekday::Sun), Ok(ymd(2004, 1, 4))); + assert_eq!(from_isoywd(2004, 2, Weekday::Mon), Ok(ymd(2004, 1, 5))); + assert_eq!(from_isoywd(2004, 2, Weekday::Sun), Ok(ymd(2004, 1, 11))); + assert_eq!(from_isoywd(2004, 52, Weekday::Mon), Ok(ymd(2004, 12, 20))); + assert_eq!(from_isoywd(2004, 52, Weekday::Sun), Ok(ymd(2004, 12, 26))); + assert_eq!(from_isoywd(2004, 53, Weekday::Mon), Ok(ymd(2004, 12, 27))); + assert_eq!(from_isoywd(2004, 53, Weekday::Sun), Ok(ymd(2005, 1, 2))); + assert_eq!(from_isoywd(2004, 54, Weekday::Mon), Err(Error::InvalidArgument)); + + assert_eq!(from_isoywd(2011, 0, Weekday::Sun), Err(Error::InvalidArgument)); + assert_eq!(from_isoywd(2011, 1, Weekday::Mon), Ok(ymd(2011, 1, 3))); + assert_eq!(from_isoywd(2011, 1, Weekday::Sun), Ok(ymd(2011, 1, 9))); + assert_eq!(from_isoywd(2011, 2, Weekday::Mon), Ok(ymd(2011, 1, 10))); + assert_eq!(from_isoywd(2011, 2, Weekday::Sun), Ok(ymd(2011, 1, 16))); + + assert_eq!(from_isoywd(2018, 51, Weekday::Mon), Ok(ymd(2018, 12, 17))); + assert_eq!(from_isoywd(2018, 51, Weekday::Sun), Ok(ymd(2018, 12, 23))); + assert_eq!(from_isoywd(2018, 52, Weekday::Mon), Ok(ymd(2018, 12, 24))); + assert_eq!(from_isoywd(2018, 52, Weekday::Sun), Ok(ymd(2018, 12, 30))); + assert_eq!(from_isoywd(2018, 53, Weekday::Mon), Err(Error::DoesNotExist)); } #[test] @@ -241,7 +241,7 @@ fn test_date_from_isoywd_and_iso_week() { .iter() { let d = NaiveDate::from_isoywd(year, week, weekday); - if let Some(d) = d { + if let Ok(d) = d { assert_eq!(d.weekday(), weekday); let w = d.iso_week(); assert_eq!(w.year(), year);