From 9d25961dc4784ccb9950cb3b8f7d14e367596a60 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 17 Jan 2024 04:23:27 +0000 Subject: [PATCH] Added chrono::MonthsExt The additions in this commit are dependent upon as-yet unreleased Chrono functionality, which will arrive in Chrono 0.4.32. Specifically, this PR has been merged, allowing inspection of the internal quantity of Months: https://github.com/chronotope/chrono/pull/1373 Due to the Chrono maintainers preferring Months.as_u32(), this commit adds Duration-style convenience methods as an external extension to the chrono::Months type. - Added num_months() and num_years() to extend chrono::Months. - Added tests and documentation. --- crates/rubedo/Cargo.toml | 2 +- crates/rubedo/src/chrono.rs | 36 ++++++++++++++++++++++++++++++- crates/rubedo/src/tests/chrono.rs | 27 +++++++++++++++++++++++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/crates/rubedo/Cargo.toml b/crates/rubedo/Cargo.toml index cc3e174..1d44fe8 100644 --- a/crates/rubedo/Cargo.toml +++ b/crates/rubedo/Cargo.toml @@ -17,7 +17,7 @@ reasons = [] [dependencies] base64 = "0.21.7" -chrono = { version = "0.4.31", features = ["alloc", "clock", "std"] } +chrono = { version = "0.4.32", features = ["alloc", "clock", "std"] } futures = "0.3.30" http = "0.2.11" http-body = "0.4.5" diff --git a/crates/rubedo/src/chrono.rs b/crates/rubedo/src/chrono.rs index eaf85c4..623f625 100644 --- a/crates/rubedo/src/chrono.rs +++ b/crates/rubedo/src/chrono.rs @@ -14,7 +14,7 @@ mod tests; // Packages use crate::sugar::s; -use chrono::{prelude::*, Duration, NaiveDate, Utc}; +use chrono::{Datelike, Duration, Months, NaiveDate, Utc}; @@ -68,6 +68,40 @@ impl DurationExt for Duration { } } +//§ MonthsExt +/// This trait provides additional functionality to [`Months`]. +pub trait MonthsExt { + // num_months + /// Returns the total number of months in the [`Months`] instance. + /// + /// This is a convenience function, to make the behaviour of [`Months`] fit + /// more closely with the behaviour of [`Duration`]. + /// + fn num_months(&self) -> u32; + + // num_years + /// Returns the total number of whole years in the [`Months`] instance. + /// + /// This is a convenience function, to make the behaviour of [`Months`] fit + /// more closely with the behaviour of [`Duration`]. + /// + fn num_years(&self) -> u32; +} + +impl MonthsExt for Months { + // num_months + fn num_months(&self) -> u32 { + self.as_u32() + } + + // num_years + #[cfg_attr( feature = "reasons", allow(clippy::integer_division, reason = "Precision is not needed here"))] + #[cfg_attr(not(feature = "reasons"), allow(clippy::integer_division))] + fn num_years(&self) -> u32 { + self.as_u32() / 12 + } +} + //§ NaiveDateExt /// This trait provides additional functionality to [`NaiveDate`]. pub trait NaiveDateExt { diff --git a/crates/rubedo/src/tests/chrono.rs b/crates/rubedo/src/tests/chrono.rs index 0f68fe4..1a14104 100644 --- a/crates/rubedo/src/tests/chrono.rs +++ b/crates/rubedo/src/tests/chrono.rs @@ -103,10 +103,37 @@ mod duration_ext { } } +//§ MonthsExt +#[cfg(test)] +mod months_ext { + use super::super::*; + + // num_months + #[test] + fn num_months() { + assert_eq!(Months::new(0).num_months(), 0); + assert_eq!(Months::new(1).num_months(), 1); + assert_eq!(Months::new(u32::MAX).num_months(), u32::MAX); + } + + // num_years + #[test] + fn num_years() { + assert_eq!(Months::new(0).num_years(), 0); + assert_eq!(Months::new(1).num_years(), 0); + assert_eq!(Months::new(11).num_years(), 0); + assert_eq!(Months::new(12).num_years(), 1); + assert_eq!(Months::new(23).num_years(), 1); + assert_eq!(Months::new(24).num_years(), 2); + assert_eq!(Months::new(u32::MAX).num_years(), u32::MAX / 12); + } +} + //§ NaiveDateExt #[cfg(test)] mod naivedate_ext { use super::super::*; + use chrono::NaiveDateTime; use claims::{assert_none, assert_some_eq}; // today