Skip to content

Commit

Permalink
Date::wrap_calendar_in_ref (#6016)
Browse files Browse the repository at this point in the history
Fixes #5859
  • Loading branch information
robertbastian authored Jan 20, 2025
1 parent 0ec545b commit c5af244
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 129 deletions.
83 changes: 3 additions & 80 deletions components/calendar/src/any_calendar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ pub enum AnyCalendar {

// TODO(#3469): Decide on the best way to implement Ord.
/// The inner date type for [`AnyCalendar`]
#[derive(Clone, PartialEq, Eq, Debug)]
#[derive(Clone, PartialEq, Eq, Debug, Copy)]
#[non_exhaustive]
pub enum AnyDateInner {
/// A date for a [`Buddhist`] calendar
Expand Down Expand Up @@ -833,7 +833,7 @@ impl AnyCalendar {
Date::new_from_iso(date.to_iso(), Ref(self))
} else {
Date {
inner: date.inner.clone(),
inner: date.inner,
calendar: Ref(self),
}
}
Expand Down Expand Up @@ -1144,11 +1144,6 @@ pub trait IntoAnyCalendar: Calendar + Sized {
/// The [`AnyCalendarKind`] enum variant associated with this calendar
fn kind(&self) -> AnyCalendarKind;

/// Convert this calendar into an [`AnyCalendar`], cloning it
///
/// You should not need to call this method directly
fn to_any_cloned(&self) -> AnyCalendar;

/// Move an [`AnyCalendar`] into a `Self`, or returning it as an error
/// if the types do not match.
///
Expand Down Expand Up @@ -1176,10 +1171,6 @@ impl IntoAnyCalendar for AnyCalendar {
self.kind()
}
#[inline]
fn to_any_cloned(&self) -> AnyCalendar {
self.clone()
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
Ok(any)
}
Expand All @@ -1189,7 +1180,7 @@ impl IntoAnyCalendar for AnyCalendar {
}
#[inline]
fn date_to_any(&self, d: &Self::DateInner) -> AnyDateInner {
d.clone()
*d
}
}

Expand All @@ -1203,10 +1194,6 @@ impl IntoAnyCalendar for Buddhist {
AnyCalendarKind::Buddhist
}
#[inline]
fn to_any_cloned(&self) -> AnyCalendar {
AnyCalendar::Buddhist(Buddhist)
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Buddhist(cal) = any {
Ok(cal)
Expand Down Expand Up @@ -1244,10 +1231,6 @@ impl IntoAnyCalendar for Chinese {
AnyCalendarKind::Chinese
}
#[inline]
fn to_any_cloned(&self) -> AnyCalendar {
AnyCalendar::Chinese(self.clone())
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Chinese(cal) = any {
Ok(cal)
Expand Down Expand Up @@ -1285,10 +1268,6 @@ impl IntoAnyCalendar for Coptic {
AnyCalendarKind::Coptic
}
#[inline]
fn to_any_cloned(&self) -> AnyCalendar {
AnyCalendar::Coptic(Coptic)
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Coptic(cal) = any {
Ok(cal)
Expand Down Expand Up @@ -1326,10 +1305,6 @@ impl IntoAnyCalendar for Dangi {
AnyCalendarKind::Dangi
}
#[inline]
fn to_any_cloned(&self) -> AnyCalendar {
AnyCalendar::Dangi(self.clone())
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Dangi(cal) = any {
Ok(cal)
Expand Down Expand Up @@ -1372,10 +1347,6 @@ impl IntoAnyCalendar for Ethiopian {
}
}
#[inline]
fn to_any_cloned(&self) -> AnyCalendar {
AnyCalendar::Ethiopian(*self)
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Ethiopian(cal) = any {
Ok(cal)
Expand Down Expand Up @@ -1413,10 +1384,6 @@ impl IntoAnyCalendar for Gregorian {
AnyCalendarKind::Gregorian
}
#[inline]
fn to_any_cloned(&self) -> AnyCalendar {
AnyCalendar::Gregorian(Gregorian)
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Gregorian(cal) = any {
Ok(cal)
Expand Down Expand Up @@ -1454,10 +1421,6 @@ impl IntoAnyCalendar for Hebrew {
AnyCalendarKind::Hebrew
}
#[inline]
fn to_any_cloned(&self) -> AnyCalendar {
AnyCalendar::Hebrew(Hebrew)
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Hebrew(cal) = any {
Ok(cal)
Expand Down Expand Up @@ -1495,10 +1458,6 @@ impl IntoAnyCalendar for Indian {
AnyCalendarKind::Indian
}
#[inline]
fn to_any_cloned(&self) -> AnyCalendar {
AnyCalendar::Indian(Indian)
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Indian(cal) = any {
Ok(cal)
Expand Down Expand Up @@ -1536,10 +1495,6 @@ impl IntoAnyCalendar for IslamicCivil {
AnyCalendarKind::IslamicCivil
}
#[inline]
fn to_any_cloned(&self) -> AnyCalendar {
AnyCalendar::IslamicCivil(*self)
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::IslamicCivil(cal) = any {
Ok(cal)
Expand Down Expand Up @@ -1577,10 +1532,6 @@ impl IntoAnyCalendar for IslamicObservational {
AnyCalendarKind::IslamicObservational
}
#[inline]
fn to_any_cloned(&self) -> AnyCalendar {
AnyCalendar::IslamicObservational(self.clone())
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::IslamicObservational(cal) = any {
Ok(cal)
Expand Down Expand Up @@ -1618,10 +1569,6 @@ impl IntoAnyCalendar for IslamicTabular {
AnyCalendarKind::IslamicTabular
}
#[inline]
fn to_any_cloned(&self) -> AnyCalendar {
AnyCalendar::IslamicTabular(*self)
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::IslamicTabular(cal) = any {
Ok(cal)
Expand Down Expand Up @@ -1659,10 +1606,6 @@ impl IntoAnyCalendar for IslamicUmmAlQura {
AnyCalendarKind::IslamicUmmAlQura
}
#[inline]
fn to_any_cloned(&self) -> AnyCalendar {
AnyCalendar::IslamicUmmAlQura(self.clone())
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::IslamicUmmAlQura(cal) = any {
Ok(cal)
Expand Down Expand Up @@ -1700,10 +1643,6 @@ impl IntoAnyCalendar for Iso {
AnyCalendarKind::Iso
}
#[inline]
fn to_any_cloned(&self) -> AnyCalendar {
AnyCalendar::Iso(Iso)
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Iso(cal) = any {
Ok(cal)
Expand Down Expand Up @@ -1741,10 +1680,6 @@ impl IntoAnyCalendar for Japanese {
AnyCalendarKind::Japanese
}
#[inline]
fn to_any_cloned(&self) -> AnyCalendar {
AnyCalendar::Japanese(self.clone())
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Japanese(cal) = any {
Ok(cal)
Expand Down Expand Up @@ -1782,10 +1717,6 @@ impl IntoAnyCalendar for JapaneseExtended {
AnyCalendarKind::JapaneseExtended
}
#[inline]
fn to_any_cloned(&self) -> AnyCalendar {
AnyCalendar::JapaneseExtended(self.clone())
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::JapaneseExtended(cal) = any {
Ok(cal)
Expand Down Expand Up @@ -1823,10 +1754,6 @@ impl IntoAnyCalendar for Persian {
AnyCalendarKind::Persian
}
#[inline]
fn to_any_cloned(&self) -> AnyCalendar {
AnyCalendar::Persian(Persian)
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Persian(cal) = any {
Ok(cal)
Expand Down Expand Up @@ -1864,10 +1791,6 @@ impl IntoAnyCalendar for Roc {
AnyCalendarKind::Roc
}
#[inline]
fn to_any_cloned(&self) -> AnyCalendar {
AnyCalendar::Roc(Roc)
}
#[inline]
fn from_any(any: AnyCalendar) -> Result<Self, AnyCalendar> {
if let AnyCalendar::Roc(cal) = any {
Ok(cal)
Expand Down
2 changes: 1 addition & 1 deletion components/calendar/src/calendar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use core::fmt;
/// unstable and prone to change, especially for `offset_date()` and `until()`.
pub trait Calendar {
/// The internal type used to represent dates
type DateInner: PartialEq + Eq + Clone + fmt::Debug;
type DateInner: Eq + Copy + fmt::Debug;
/// Construct a date from era/month codes and fields
///
/// The year is extended_year if no era is provided
Expand Down
57 changes: 31 additions & 26 deletions components/calendar/src/date.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,19 @@ impl<C: Calendar> AsCalendar for C {
}
}

impl<C: Calendar> AsCalendar for Rc<C> {
type Calendar = C;
impl<C: AsCalendar> AsCalendar for Rc<C> {
type Calendar = C::Calendar;
#[inline]
fn as_calendar(&self) -> &C {
self
fn as_calendar(&self) -> &Self::Calendar {
self.as_ref().as_calendar()
}
}

impl<C: Calendar> AsCalendar for Arc<C> {
type Calendar = C;
impl<C: AsCalendar> AsCalendar for Arc<C> {
type Calendar = C::Calendar;
#[inline]
fn as_calendar(&self) -> &C {
self
fn as_calendar(&self) -> &Self::Calendar {
self.as_ref().as_calendar()
}
}

Expand All @@ -67,11 +67,11 @@ impl<C> Clone for Ref<'_, C> {
}
}

impl<C: Calendar> AsCalendar for Ref<'_, C> {
type Calendar = C;
impl<C: AsCalendar> AsCalendar for Ref<'_, C> {
type Calendar = C::Calendar;
#[inline]
fn as_calendar(&self) -> &C {
self.0
fn as_calendar(&self) -> &Self::Calendar {
self.0.as_calendar()
}
}

Expand Down Expand Up @@ -344,28 +344,38 @@ impl Date<Iso> {
}
}

impl<C: IntoAnyCalendar, A: AsCalendar<Calendar = C>> Date<A> {
impl<C: IntoAnyCalendar> Date<C> {
/// Type-erase the date, converting it to a date for [`AnyCalendar`]
pub fn to_any(&self) -> Date<AnyCalendar> {
let cal = self.calendar();
Date::from_raw(cal.date_to_any(self.inner()), cal.to_any_cloned())
pub fn to_any(self) -> Date<AnyCalendar> {
Date::from_raw(
self.calendar.date_to_any(&self.inner),
self.calendar.to_any(),
)
}
}

impl<C: Calendar> Date<C> {
impl<A: AsCalendar> Date<A> {
/// Wrap the calendar type in `Rc<T>`
///
/// Useful when paired with [`Self::to_any()`] to obtain a `Date<Rc<AnyCalendar>>`
pub fn wrap_calendar_in_rc(self) -> Date<Rc<C>> {
pub fn wrap_calendar_in_rc(self) -> Date<Rc<A>> {
Date::from_raw(self.inner, Rc::new(self.calendar))
}

/// Wrap the calendar type in `Arc<T>`
///
/// Useful when paired with [`Self::to_any()`] to obtain a `Date<Rc<AnyCalendar>>`
pub fn wrap_calendar_in_arc(self) -> Date<Arc<C>> {
pub fn wrap_calendar_in_arc(self) -> Date<Arc<A>> {
Date::from_raw(self.inner, Arc::new(self.calendar))
}

/// Wrap the calendar type in `Ref<T>`
///
/// Useful for converting a `&Date<C>` into an equivalent `Date<D>` without cloning
/// the calendar.
pub fn wrap_calendar_in_ref(&self) -> Date<Ref<A>> {
Date::from_raw(self.inner, Ref(&self.calendar))
}
}

impl<C, A, B> PartialEq<Date<B>> for Date<A>
Expand Down Expand Up @@ -433,18 +443,13 @@ impl<A: AsCalendar> fmt::Debug for Date<A> {
impl<A: AsCalendar + Clone> Clone for Date<A> {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
inner: self.inner,
calendar: self.calendar.clone(),
}
}
}

impl<A> Copy for Date<A>
where
A: AsCalendar + Copy,
<<A as AsCalendar>::Calendar as Calendar>::DateInner: Copy,
{
}
impl<A> Copy for Date<A> where A: AsCalendar + Copy {}

#[cfg(test)]
mod tests {
Expand Down
2 changes: 1 addition & 1 deletion components/calendar/src/japanese.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
//!
//! let date_iso = Date::try_new_iso(1970, 1, 2)
//! .expect("Failed to initialize ISO Date instance.");
//! let date_japanese = Date::new_from_iso(date_iso, japanese_calendar.clone());
//! let date_japanese = Date::new_from_iso(date_iso, japanese_calendar);
//!
//! assert_eq!(date_japanese.year().era_year_or_extended(), 45);
//! assert_eq!(date_japanese.month().ordinal, 1);
Expand Down
8 changes: 3 additions & 5 deletions components/datetime/src/scaffold/calendar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ impl<C: IntoAnyCalendar, A: AsCalendar<Calendar = C>> ConvertCalendar for Date<A
type Converted<'a> = Date<Ref<'a, AnyCalendar>>;
#[inline]
fn to_calendar<'a>(&self, calendar: &'a AnyCalendar) -> Self::Converted<'a> {
self.to_any().to_calendar(Ref(calendar))
self.to_calendar(Ref(calendar))
}
}

Expand All @@ -409,9 +409,8 @@ impl<C: IntoAnyCalendar, A: AsCalendar<Calendar = C>> ConvertCalendar for DateTi
type Converted<'a> = DateTime<Ref<'a, AnyCalendar>>;
#[inline]
fn to_calendar<'a>(&self, calendar: &'a AnyCalendar) -> Self::Converted<'a> {
let date = self.date.to_any().to_calendar(Ref(calendar));
DateTime {
date,
date: self.date.to_calendar(Ref(calendar)),
time: self.time,
}
}
Expand All @@ -423,9 +422,8 @@ impl<C: IntoAnyCalendar, A: AsCalendar<Calendar = C>, Z: Copy> ConvertCalendar
type Converted<'a> = ZonedDateTime<Ref<'a, AnyCalendar>, Z>;
#[inline]
fn to_calendar<'a>(&self, calendar: &'a AnyCalendar) -> Self::Converted<'a> {
let date = self.date.to_any().to_calendar(Ref(calendar));
ZonedDateTime {
date,
date: self.date.to_calendar(Ref(calendar)),
time: self.time,
zone: self.zone,
}
Expand Down
Loading

0 comments on commit c5af244

Please sign in to comment.