Change IsoWeek::from_yof to consuming ordinal and year_flags

remove `Of::isoweekdate_raw`
This commit is contained in:
Paul Dicker 2023-07-30 13:14:45 +02:00 committed by Paul Dicker
parent 92b576b219
commit 583812d700
3 changed files with 36 additions and 23 deletions

View File

@ -1688,7 +1688,7 @@ impl Datelike for NaiveDate {
#[inline]
fn iso_week(&self) -> IsoWeek {
IsoWeek::from_yof(self.year(), self.of())
IsoWeek::from_yof(self.year(), self.ordinal(), self.of().flags())
}
/// Makes a new `NaiveDate` with the year number changed, while keeping the same month and day.
@ -2516,7 +2516,7 @@ mod serde {
#[cfg(test)]
mod tests {
use super::{Days, Months, NaiveDate, MAX_YEAR, MIN_YEAR};
use crate::naive::internals::YearFlags;
use crate::naive::internals::{YearFlags, A, AG, B, BA, C, CB, D, DC, E, ED, F, FE, G, GF};
use crate::{Datelike, TimeDelta, Weekday};
// as it is hard to verify year flags in `NaiveDate::MIN` and `NaiveDate::MAX`,
@ -3375,6 +3375,36 @@ mod tests {
}
}
#[test]
fn test_isoweekdate_with_yearflags() {
for (year, year_flags, _) in YEAR_FLAGS {
// January 4 should be in the first week
let jan4 = NaiveDate::from_ymd_opt(year, 1, 4).unwrap();
let iso_week = jan4.iso_week();
assert_eq!(jan4.of().flags(), year_flags);
assert_eq!(iso_week.week(), 1);
}
}
// Used for testing some methods with all combinations of `YearFlags`.
// (year, flags, first weekday of year)
const YEAR_FLAGS: [(i32, YearFlags, Weekday); 14] = [
(2006, A, Weekday::Sun),
(2005, B, Weekday::Sat),
(2010, C, Weekday::Fri),
(2009, D, Weekday::Thu),
(2003, E, Weekday::Wed),
(2002, F, Weekday::Tue),
(2001, G, Weekday::Mon),
(2012, AG, Weekday::Sun),
(2000, BA, Weekday::Sat),
(2016, CB, Weekday::Fri),
(2004, DC, Weekday::Thu),
(2020, ED, Weekday::Wed),
(2008, FE, Weekday::Tue),
(2024, GF, Weekday::Mon),
];
#[test]
#[cfg(feature = "rkyv-validation")]
fn test_rkyv_validation() {

View File

@ -322,14 +322,6 @@ impl Of {
weekday_from_u32_mod7((of >> 4) + (of & 0b111))
}
#[inline]
pub(super) fn isoweekdate_raw(&self) -> (u32, Weekday) {
// week ordinal = ordinal + delta
let Of(of) = *self;
let weekord = (of >> 4).wrapping_add(self.flags().isoweek_delta());
(weekord / 7, weekday_from_u32_mod7(weekord))
}
#[cfg_attr(feature = "cargo-clippy", allow(clippy::wrong_self_convention))]
#[inline]
pub(super) const fn to_mdf(&self) -> Mdf {
@ -740,15 +732,6 @@ mod tests {
}
}
#[test]
fn test_of_isoweekdate_raw() {
for &flags in FLAGS.iter() {
// January 4 should be in the first week
let (week, _) = Of::new(4 /* January 4 */, flags).unwrap().isoweekdate_raw();
assert_eq!(week, 1);
}
}
#[test]
fn test_of_to_mdf() {
for i in 0u32..=8192 {

View File

@ -5,7 +5,7 @@
use core::fmt;
use super::internals::{Of, YearFlags};
use super::internals::YearFlags;
#[cfg(any(feature = "rkyv", feature = "rkyv-16", feature = "rkyv-32", feature = "rkyv-64"))]
use rkyv::{Archive, Deserialize, Serialize};
@ -38,14 +38,14 @@ impl IsoWeek {
// because the year range for the week date and the calendar date do not match and
// it is confusing to have a date that is out of range in one and not in another.
// currently we sidestep this issue by making `IsoWeek` fully dependent of `Datelike`.
pub(super) fn from_yof(year: i32, of: Of) -> Self {
let (rawweek, _) = of.isoweekdate_raw();
pub(super) fn from_yof(year: i32, ordinal: u32, year_flags: YearFlags) -> Self {
let rawweek = (ordinal + year_flags.isoweek_delta()) / 7;
let (year, week) = if rawweek < 1 {
// previous year
let prevlastweek = YearFlags::from_year(year - 1).nisoweeks();
(year - 1, prevlastweek)
} else {
let lastweek = of.flags().nisoweeks();
let lastweek = year_flags.nisoweeks();
if rawweek > lastweek {
// next year
(year + 1, 1)