From 0f33b98e75cd6e6aa25be70b26bf930d031216cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Juli=C3=A1n=20Espina?= Date: Mon, 5 Feb 2024 06:12:48 +0000 Subject: [PATCH] Simplify Temporal APIs (#3653) * Simplify Temporal APIs * cargo fmt * Unroll deletion of context-free API --- .../src/builtins/temporal/calendar/object.rs | 136 +++--------- .../src/builtins/temporal/plain_date/mod.rs | 30 +-- .../builtins/temporal/plain_date_time/mod.rs | 26 +-- .../src/builtins/temporal/time_zone/custom.rs | 22 +- core/temporal/src/components/calendar.rs | 198 +++++++++--------- core/temporal/src/components/date.rs | 107 +++------- core/temporal/src/components/datetime.rs | 79 ++++--- core/temporal/src/components/duration.rs | 8 +- core/temporal/src/components/duration/date.rs | 4 +- core/temporal/src/components/tz.rs | 29 +-- core/temporal/src/components/zoneddatetime.rs | 104 +++------ 11 files changed, 277 insertions(+), 466 deletions(-) diff --git a/core/engine/src/builtins/temporal/calendar/object.rs b/core/engine/src/builtins/temporal/calendar/object.rs index 64e0ef3d99..04ab9aa3f7 100644 --- a/core/engine/src/builtins/temporal/calendar/object.rs +++ b/core/engine/src/builtins/temporal/calendar/object.rs @@ -12,12 +12,11 @@ use crate::{ property::PropertyKey, Context, JsObject, JsString, JsValue, }; -use std::any::Any; use boa_macros::utf16; use boa_temporal::{ components::{ - calendar::{CalendarDateLike, CalendarProtocol, DateTypes}, + calendar::{CalendarDateLike, CalendarProtocol}, Date, Duration, MonthDay, YearMonth, }, options::ArithmeticOverflow, @@ -29,29 +28,18 @@ use plain_date_time::PlainDateTime; use plain_month_day::PlainMonthDay; use plain_year_month::PlainYearMonth; -/// The custom data types for a Custom `JsObject` Calendar. -#[derive(Debug, Clone, Copy)] -pub struct CustomDateLikes; - -impl DateTypes for CustomDateLikes { +impl CalendarProtocol for JsObject { type Date = JsObject; type DateTime = JsObject; type YearMonth = JsObject; type MonthDay = JsObject; -} - -impl CalendarProtocol for JsObject { - type DateLikes = CustomDateLikes; + type Context = Context; fn date_from_fields( &self, fields: &mut TemporalFields, overflow: ArithmeticOverflow, - context: &mut dyn Any, + context: &mut Context, ) -> TemporalResult> { - let context = context - .downcast_mut::() - .expect("Context was not provided for a CustomCalendar."); - let method = self .get(utf16!("dateFromFields"), context) .expect("method must exist on a object that implements the CalendarProtocol."); @@ -97,12 +85,8 @@ impl CalendarProtocol for JsObject { &self, fields: &mut TemporalFields, overflow: ArithmeticOverflow, - context: &mut dyn Any, + context: &mut Context, ) -> TemporalResult> { - let context = context - .downcast_mut::() - .expect("Context was not provided for a CustomCalendar."); - let method = self .get(utf16!("yearMonthFromFields"), context) .expect("method must exist on a object that implements the CalendarProtocol."); @@ -150,12 +134,8 @@ impl CalendarProtocol for JsObject { &self, fields: &mut TemporalFields, overflow: ArithmeticOverflow, - context: &mut dyn Any, + context: &mut Context, ) -> TemporalResult> { - let context = context - .downcast_mut::() - .expect("Context was not provided for a CustomCalendar."); - let method = self .get(utf16!("yearMonthFromFields"), context) .expect("method must exist on a object that implements the CalendarProtocol."); @@ -204,7 +184,7 @@ impl CalendarProtocol for JsObject { _date: &Date, _duration: &Duration, _overflow: ArithmeticOverflow, - _context: &mut dyn Any, + _context: &mut Context, ) -> TemporalResult> { // TODO Err(TemporalError::general("Not yet implemented.")) @@ -215,7 +195,7 @@ impl CalendarProtocol for JsObject { _one: &Date, _two: &Date, _largest_unit: boa_temporal::options::TemporalUnit, - _context: &mut dyn Any, + _context: &mut Context, ) -> TemporalResult { // TODO Err(TemporalError::general("Not yet implemented.")) @@ -224,7 +204,7 @@ impl CalendarProtocol for JsObject { fn era( &self, _: &CalendarDateLike, - _: &mut dyn Any, + _: &mut Context, ) -> TemporalResult>> { // Return undefined as custom calendars do not implement -> Currently. Ok(None) @@ -233,7 +213,7 @@ impl CalendarProtocol for JsObject { fn era_year( &self, _: &CalendarDateLike, - _: &mut dyn Any, + _: &mut Context, ) -> TemporalResult> { // Return undefined as custom calendars do not implement -> Currently. Ok(None) @@ -242,12 +222,8 @@ impl CalendarProtocol for JsObject { fn year( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Context, ) -> TemporalResult { - let context = context - .downcast_mut::() - .expect("Context was not provided for a CustomCalendar."); - let date_like = date_like_to_object(date_like, context)?; let method = self @@ -288,12 +264,8 @@ impl CalendarProtocol for JsObject { fn month( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Context, ) -> TemporalResult { - let context = context - .downcast_mut::() - .expect("Context was not provided for a CustomCalendar."); - let date_like = date_like_to_object(date_like, context)?; let method = self @@ -334,12 +306,8 @@ impl CalendarProtocol for JsObject { fn month_code( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Context, ) -> TemporalResult> { - let context = context - .downcast_mut::() - .expect("Context was not provided for a CustomCalendar."); - let date_like = date_like_to_object(date_like, context)?; let method = self @@ -365,12 +333,8 @@ impl CalendarProtocol for JsObject { fn day( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Context, ) -> TemporalResult { - let context = context - .downcast_mut::() - .expect("Context was not provided for a CustomCalendar."); - let date_like = date_like_to_object(date_like, context)?; let method = self @@ -411,12 +375,8 @@ impl CalendarProtocol for JsObject { fn day_of_week( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Context, ) -> TemporalResult { - let context = context - .downcast_mut::() - .expect("Context was not provided for a CustomCalendar."); - let date_like = date_like_to_object(date_like, context)?; let method = self @@ -459,12 +419,8 @@ impl CalendarProtocol for JsObject { fn day_of_year( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Context, ) -> TemporalResult { - let context = context - .downcast_mut::() - .expect("Context was not provided for a CustomCalendar."); - let date_like = date_like_to_object(date_like, context)?; let method = self @@ -507,12 +463,8 @@ impl CalendarProtocol for JsObject { fn week_of_year( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Context, ) -> TemporalResult { - let context = context - .downcast_mut::() - .expect("Context was not provided for a CustomCalendar."); - let date_like = date_like_to_object(date_like, context)?; let method = self @@ -555,12 +507,8 @@ impl CalendarProtocol for JsObject { fn year_of_week( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Context, ) -> TemporalResult { - let context = context - .downcast_mut::() - .expect("Context was not provided for a CustomCalendar."); - let date_like = date_like_to_object(date_like, context)?; let method = self @@ -596,12 +544,8 @@ impl CalendarProtocol for JsObject { fn days_in_week( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Context, ) -> TemporalResult { - let context = context - .downcast_mut::() - .expect("Context was not provided for a CustomCalendar."); - let date_like = date_like_to_object(date_like, context)?; let method = self @@ -644,12 +588,8 @@ impl CalendarProtocol for JsObject { fn days_in_month( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Context, ) -> TemporalResult { - let context = context - .downcast_mut::() - .expect("Context was not provided for a CustomCalendar."); - let date_like = date_like_to_object(date_like, context)?; let method = self @@ -693,12 +633,8 @@ impl CalendarProtocol for JsObject { fn days_in_year( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Context, ) -> TemporalResult { - let context = context - .downcast_mut::() - .expect("Context was not provided for a CustomCalendar."); - let date_like = date_like_to_object(date_like, context)?; let method = self @@ -741,12 +677,8 @@ impl CalendarProtocol for JsObject { fn months_in_year( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Context, ) -> TemporalResult { - let context = context - .downcast_mut::() - .expect("Context was not provided for a CustomCalendar."); - let date_like = date_like_to_object(date_like, context)?; let method = self @@ -791,12 +723,8 @@ impl CalendarProtocol for JsObject { fn in_leap_year( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Context, ) -> TemporalResult { - let context = context - .downcast_mut::() - .expect("Context was not provided for a CustomCalendar."); - let date_like = date_like_to_object(date_like, context)?; let method = self @@ -818,11 +746,7 @@ impl CalendarProtocol for JsObject { Ok(result) } - fn fields(&self, fields: Vec, context: &mut dyn Any) -> TemporalResult> { - let context = context - .downcast_mut::() - .expect("Context was not provided for a CustomCalendar."); - + fn fields(&self, fields: Vec, context: &mut Context) -> TemporalResult> { let fields_js = Array::create_array_from_list( fields.iter().map(|s| JsString::from(s.clone()).into()), context, @@ -867,12 +791,8 @@ impl CalendarProtocol for JsObject { &self, fields: &TemporalFields, additional_fields: &TemporalFields, - context: &mut dyn Any, + context: &mut Context, ) -> TemporalResult { - let context = context - .downcast_mut::() - .expect("Context was not provided for a CustomCalendar."); - let fields = JsObject::from_temporal_fields(fields, context) .map_err(|e| TemporalError::general(e.to_string()))?; let add_fields = JsObject::from_temporal_fields(additional_fields, context) @@ -901,11 +821,7 @@ impl CalendarProtocol for JsObject { object_to_temporal_fields(&o, context).map_err(|e| TemporalError::general(e.to_string())) } - fn identifier(&self, context: &mut dyn Any) -> TemporalResult { - let context = context - .downcast_mut::() - .expect("Context was not provided for a CustomCalendar."); - + fn identifier(&self, context: &mut Context) -> TemporalResult { let identifier = self .__get__( &PropertyKey::from(utf16!("id")), diff --git a/core/engine/src/builtins/temporal/plain_date/mod.rs b/core/engine/src/builtins/temporal/plain_date/mod.rs index 596e1bf400..06abf25a6c 100644 --- a/core/engine/src/builtins/temporal/plain_date/mod.rs +++ b/core/engine/src/builtins/temporal/plain_date/mod.rs @@ -284,7 +284,7 @@ impl PlainDate { .into()); }; - Ok(InnerDate::::contextualized_year(&date, context)?.into()) + Ok(InnerDate::::contextual_year(&date, context)?.into()) } /// 3.3.5 get `Temporal.PlainDate.prototype.month` @@ -299,7 +299,7 @@ impl PlainDate { .into()); }; - Ok(InnerDate::::contextualized_month(&date, context)?.into()) + Ok(InnerDate::::contextual_month(&date, context)?.into()) } /// 3.3.6 get Temporal.PlainDate.prototype.monthCode @@ -314,10 +314,10 @@ impl PlainDate { .into()); }; - Ok(JsString::from( - InnerDate::::contextualized_month_code(&date, context)?.as_str(), + Ok( + JsString::from(InnerDate::::contextual_month_code(&date, context)?.as_str()) + .into(), ) - .into()) } /// 3.3.7 get `Temporal.PlainDate.prototype.day` @@ -332,7 +332,7 @@ impl PlainDate { .into()); }; - Ok(InnerDate::::contextualized_day(&date, context)?.into()) + Ok(InnerDate::::contextual_day(&date, context)?.into()) } /// 3.3.8 get `Temporal.PlainDate.prototype.dayOfWeek` @@ -347,7 +347,7 @@ impl PlainDate { .into()); }; - Ok(InnerDate::::contextualized_day_of_week(&date, context)?.into()) + Ok(InnerDate::::contextual_day_of_week(&date, context)?.into()) } /// 3.3.9 get `Temporal.PlainDate.prototype.dayOfYear` @@ -362,7 +362,7 @@ impl PlainDate { .into()); }; - Ok(InnerDate::::contextualized_day_of_year(&date, context)?.into()) + Ok(InnerDate::::contextual_day_of_year(&date, context)?.into()) } /// 3.3.10 get `Temporal.PlainDate.prototype.weekOfYear` @@ -377,7 +377,7 @@ impl PlainDate { .into()); }; - Ok(InnerDate::::contextualized_week_of_year(&date, context)?.into()) + Ok(InnerDate::::contextual_week_of_year(&date, context)?.into()) } /// 3.3.11 get `Temporal.PlainDate.prototype.yearOfWeek` @@ -392,7 +392,7 @@ impl PlainDate { .into()); }; - Ok(InnerDate::::contextualized_year_of_week(&date, context)?.into()) + Ok(InnerDate::::contextual_year_of_week(&date, context)?.into()) } /// 3.3.12 get `Temporal.PlainDate.prototype.daysInWeek` @@ -407,7 +407,7 @@ impl PlainDate { .into()); }; - Ok(InnerDate::::contextualized_days_in_week(&date, context)?.into()) + Ok(InnerDate::::contextual_days_in_week(&date, context)?.into()) } /// 3.3.13 get `Temporal.PlainDate.prototype.daysInMonth` @@ -426,7 +426,7 @@ impl PlainDate { .into()); }; - Ok(InnerDate::::contextualized_days_in_month(&date, context)?.into()) + Ok(InnerDate::::contextual_days_in_month(&date, context)?.into()) } /// 3.3.14 get `Temporal.PlainDate.prototype.daysInYear` @@ -441,7 +441,7 @@ impl PlainDate { .into()); }; - Ok(InnerDate::::contextualized_days_in_year(&date, context)?.into()) + Ok(InnerDate::::contextual_days_in_year(&date, context)?.into()) } /// 3.3.15 get `Temporal.PlainDate.prototype.monthsInYear` @@ -460,7 +460,7 @@ impl PlainDate { .into()); }; - Ok(InnerDate::::contextualized_months_in_year(&date, context)?.into()) + Ok(InnerDate::::contextual_months_in_year(&date, context)?.into()) } /// 3.3.16 get `Temporal.PlainDate.prototype.inLeapYear` @@ -475,7 +475,7 @@ impl PlainDate { .into()); }; - Ok(InnerDate::::contextualized_in_leap_year(&date, context)?.into()) + Ok(InnerDate::::contextual_in_leap_year(&date, context)?.into()) } } diff --git a/core/engine/src/builtins/temporal/plain_date_time/mod.rs b/core/engine/src/builtins/temporal/plain_date_time/mod.rs index 143553edf2..9fb73aea04 100644 --- a/core/engine/src/builtins/temporal/plain_date_time/mod.rs +++ b/core/engine/src/builtins/temporal/plain_date_time/mod.rs @@ -372,7 +372,7 @@ impl PlainDateTime { .into()); }; - Ok(InnerDateTime::::contextualized_year(&date, context)?.into()) + Ok(InnerDateTime::::contextual_year(&date, context)?.into()) } /// 5.3.5 get `Temporal.PlainDateTime.prototype.month` @@ -387,7 +387,7 @@ impl PlainDateTime { .into()); }; - Ok(InnerDateTime::::contextualized_month(&date, context)?.into()) + Ok(InnerDateTime::::contextual_month(&date, context)?.into()) } /// 5.3.6 get Temporal.PlainDateTime.prototype.monthCode @@ -403,7 +403,7 @@ impl PlainDateTime { }; Ok(JsString::from( - InnerDateTime::::contextualized_month_code(&date, context)?.as_str(), + InnerDateTime::::contextual_month_code(&date, context)?.as_str(), ) .into()) } @@ -420,7 +420,7 @@ impl PlainDateTime { .into()); }; - Ok(InnerDateTime::::contextualized_day(&date, context)?.into()) + Ok(InnerDateTime::::contextual_day(&date, context)?.into()) } /// 5.3.8 get `Temporal.PlainDateTime.prototype.hour` @@ -525,7 +525,7 @@ impl PlainDateTime { .into()); }; - Ok(InnerDateTime::::contextualized_day_of_week(&date, context)?.into()) + Ok(InnerDateTime::::contextual_day_of_week(&date, context)?.into()) } /// 5.3.15 get `Temporal.PlainDateTime.prototype.dayOfYear` @@ -540,7 +540,7 @@ impl PlainDateTime { .into()); }; - Ok(InnerDateTime::::contextualized_day_of_year(&date, context)?.into()) + Ok(InnerDateTime::::contextual_day_of_year(&date, context)?.into()) } /// 5.3.16 get `Temporal.PlainDateTime.prototype.weekOfYear` @@ -555,7 +555,7 @@ impl PlainDateTime { .into()); }; - Ok(InnerDateTime::::contextualized_week_of_year(&date, context)?.into()) + Ok(InnerDateTime::::contextual_week_of_year(&date, context)?.into()) } /// 5.3.17 get `Temporal.PlainDateTime.prototype.yearOfWeek` @@ -570,7 +570,7 @@ impl PlainDateTime { .into()); }; - Ok(InnerDateTime::::contextualized_year_of_week(&date, context)?.into()) + Ok(InnerDateTime::::contextual_year_of_week(&date, context)?.into()) } /// 5.3.18 get `Temporal.PlainDateTime.prototype.daysInWeek` @@ -585,7 +585,7 @@ impl PlainDateTime { .into()); }; - Ok(InnerDateTime::::contextualized_days_in_week(&date, context)?.into()) + Ok(InnerDateTime::::contextual_days_in_week(&date, context)?.into()) } /// 5.3.19 get `Temporal.PlainDateTime.prototype.daysInMonth` @@ -604,7 +604,7 @@ impl PlainDateTime { .into()); }; - Ok(InnerDateTime::::contextualized_days_in_month(&date, context)?.into()) + Ok(InnerDateTime::::contextual_days_in_month(&date, context)?.into()) } /// 5.3.20 get `Temporal.PlainDateTime.prototype.daysInYear` @@ -619,7 +619,7 @@ impl PlainDateTime { .into()); }; - Ok(InnerDateTime::::contextualized_days_in_year(&date, context)?.into()) + Ok(InnerDateTime::::contextual_days_in_year(&date, context)?.into()) } /// 5.3.21 get `Temporal.PlainDateTime.prototype.monthsInYear` @@ -638,7 +638,7 @@ impl PlainDateTime { .into()); }; - Ok(InnerDateTime::::contextualized_months_in_year(&date, context)?.into()) + Ok(InnerDateTime::::contextual_months_in_year(&date, context)?.into()) } /// 5.3.22 get `Temporal.PlainDateTime.prototype.inLeapYear` @@ -653,7 +653,7 @@ impl PlainDateTime { .into()); }; - Ok(InnerDateTime::::contextualized_in_leap_year(&date, context)?.into()) + Ok(InnerDateTime::::contextual_in_leap_year(&date, context)?.into()) } } diff --git a/core/engine/src/builtins/temporal/time_zone/custom.rs b/core/engine/src/builtins/temporal/time_zone/custom.rs index a8aaf33aa2..344943b140 100644 --- a/core/engine/src/builtins/temporal/time_zone/custom.rs +++ b/core/engine/src/builtins/temporal/time_zone/custom.rs @@ -14,11 +14,8 @@ pub(crate) struct JsCustomTimeZone { } impl TzProtocol for JsCustomTimeZone { - fn get_offset_nanos_for(&self, ctx: &mut dyn std::any::Any) -> TemporalResult { - let context = ctx - .downcast_mut::() - .expect("Context was not provided for a CustomTz"); - + type Context = Context; + fn get_offset_nanos_for(&self, context: &mut Context) -> TemporalResult { let method = self .tz .get(utf16!("getOffsetNanosFor"), context) @@ -39,23 +36,12 @@ impl TzProtocol for JsCustomTimeZone { Ok(bigint.as_inner().clone()) } - fn get_possible_instant_for( - &self, - ctx: &mut dyn std::any::Any, - ) -> TemporalResult> { - let _context = ctx - .downcast_mut::() - .expect("Context was not provided for a CustomTz"); - + fn get_possible_instant_for(&self, _context: &mut Context) -> TemporalResult> { // TODO: Implement once Instant has been migrated to `boa_temporal`'s Instant. Err(TemporalError::range().with_message("Not yet implemented.")) } - fn id(&self, ctx: &mut dyn std::any::Any) -> TemporalResult { - let context = ctx - .downcast_mut::() - .expect("Context was not provided for a CustomTz"); - + fn id(&self, context: &mut Context) -> TemporalResult { let ident = self .tz .__get__( diff --git a/core/temporal/src/components/calendar.rs b/core/temporal/src/components/calendar.rs index 22b9f3e6cd..9543cb8062 100644 --- a/core/temporal/src/components/calendar.rs +++ b/core/temporal/src/components/calendar.rs @@ -8,7 +8,7 @@ //! the calendar protocol), but it does aim to provide the necessary tools and API for //! implementing one. -use std::{any::Any, str::FromStr}; +use std::str::FromStr; use crate::{ components::{Date, DateTime, Duration, MonthDay, YearMonth}, @@ -88,13 +88,13 @@ impl From<&[String]> for CalendarFieldsType { #[derive(Debug)] pub enum CalendarDateLike { /// Represents a user-defined `Date` datelike - CustomDate(<::DateLikes as DateTypes>::Date), + CustomDate(C::Date), /// Represents a user-defined `DateTime` datelike - CustomDateTime(<::DateLikes as DateTypes>::DateTime), + CustomDateTime(C::DateTime), /// Represents a user-defined `YearMonth` datelike - CustomYearMonth(<::DateLikes as DateTypes>::YearMonth), + CustomYearMonth(C::YearMonth), /// Represents a user-defined `MonthDay` datelike - CustomMonthDay(<::DateLikes as DateTypes>::MonthDay), + CustomMonthDay(C::MonthDay), /// Represents a `DateTime`. DateTime(DateTime), /// Represents a `Date`. @@ -117,45 +117,41 @@ impl CalendarDateLike { } } -// TODO: DateTypes should implement a trait -> `ToTemporalDate`: `GetCalendarSlot` -/// A trait for implementing `DateLike` types -pub trait DateTypes { +// ==== CalendarProtocol trait ==== + +/// A trait for implementing a Builtin Calendar's Calendar Protocol in Rust. +pub trait CalendarProtocol: Clone { /// A Custom `Date` Type for an associated `CalendarProtocol`. Default `Date` - type Date: IsoDateSlots + GetCalendarSlot + Clone + core::fmt::Debug; + type Date: IsoDateSlots + GetCalendarSlot + Clone + core::fmt::Debug; /// A Custom `DateTime` Type for an associated `CalendarProtocol`. Default `DateTime` - type DateTime: IsoDateSlots + GetCalendarSlot + Clone + core::fmt::Debug; + type DateTime: IsoDateSlots + GetCalendarSlot + Clone + core::fmt::Debug; /// A Custom `YearMonth` Type for an associated `CalendarProtocol`. Default `YearMonth` - type YearMonth: IsoDateSlots + GetCalendarSlot + Clone + core::fmt::Debug; + type YearMonth: IsoDateSlots + GetCalendarSlot + Clone + core::fmt::Debug; /// A Custom `MonthDay` Type for an associated `CalendarProtocol`. Default `MonthDay` - type MonthDay: IsoDateSlots + GetCalendarSlot + Clone + core::fmt::Debug; -} - -// ==== CalendarProtocol trait ==== + type MonthDay: IsoDateSlots + GetCalendarSlot + Clone + core::fmt::Debug; + /// The context passed to every method of the `CalendarProtocol`. + type Context; -/// A trait for implementing a Builtin Calendar's Calendar Protocol in Rust. -pub trait CalendarProtocol: Clone { - /// Registers a valid set of custom `CalendarDateLike` values. - type DateLikes: DateTypes; /// Creates a `Temporal.PlainDate` object from provided fields. fn date_from_fields( &self, fields: &mut TemporalFields, overflow: ArithmeticOverflow, - context: &mut dyn Any, + context: &mut Self::Context, ) -> TemporalResult>; /// Creates a `Temporal.PlainYearMonth` object from the provided fields. fn year_month_from_fields( &self, fields: &mut TemporalFields, overflow: ArithmeticOverflow, - context: &mut dyn Any, + context: &mut Self::Context, ) -> TemporalResult>; /// Creates a `Temporal.PlainMonthDay` object from the provided fields. fn month_day_from_fields( &self, fields: &mut TemporalFields, overflow: ArithmeticOverflow, - context: &mut dyn Any, + context: &mut Self::Context, ) -> TemporalResult>; /// Returns a `Temporal.PlainDate` based off an added date. fn date_add( @@ -163,7 +159,7 @@ pub trait CalendarProtocol: Clone { date: &Date, duration: &Duration, overflow: ArithmeticOverflow, - context: &mut dyn Any, + context: &mut Self::Context, ) -> TemporalResult>; /// Returns a `Temporal.Duration` representing the duration between two dates. fn date_until( @@ -171,106 +167,114 @@ pub trait CalendarProtocol: Clone { one: &Date, two: &Date, largest_unit: TemporalUnit, - context: &mut dyn Any, + context: &mut Self::Context, ) -> TemporalResult; /// Returns the era for a given `temporaldatelike`. fn era( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Self::Context, ) -> TemporalResult>>; /// Returns the era year for a given `temporaldatelike` fn era_year( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Self::Context, ) -> TemporalResult>; /// Returns the `year` for a given `temporaldatelike` fn year( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Self::Context, ) -> TemporalResult; /// Returns the `month` for a given `temporaldatelike` fn month( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Self::Context, ) -> TemporalResult; // Note: Best practice would probably be to switch to a MonthCode enum after extraction. /// Returns the `monthCode` for a given `temporaldatelike` fn month_code( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Self::Context, ) -> TemporalResult>; /// Returns the `day` for a given `temporaldatelike` - fn day(&self, date_like: &CalendarDateLike, context: &mut dyn Any) -> TemporalResult; + fn day( + &self, + date_like: &CalendarDateLike, + context: &mut Self::Context, + ) -> TemporalResult; /// Returns a value representing the day of the week for a date. fn day_of_week( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Self::Context, ) -> TemporalResult; /// Returns a value representing the day of the year for a given calendar. fn day_of_year( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Self::Context, ) -> TemporalResult; /// Returns a value representing the week of the year for a given calendar. fn week_of_year( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Self::Context, ) -> TemporalResult; /// Returns the year of a given week. fn year_of_week( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Self::Context, ) -> TemporalResult; /// Returns the days in a week for a given calendar. fn days_in_week( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Self::Context, ) -> TemporalResult; /// Returns the days in a month for a given calendar. fn days_in_month( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Self::Context, ) -> TemporalResult; /// Returns the days in a year for a given calendar. fn days_in_year( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Self::Context, ) -> TemporalResult; /// Returns the months in a year for a given calendar. fn months_in_year( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Self::Context, ) -> TemporalResult; /// Returns whether a value is within a leap year according to the designated calendar. fn in_leap_year( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut Self::Context, ) -> TemporalResult; /// Return the fields for a value. - fn fields(&self, fields: Vec, context: &mut dyn Any) -> TemporalResult>; + fn fields( + &self, + fields: Vec, + context: &mut Self::Context, + ) -> TemporalResult>; /// Merge fields based on the calendar and provided values. fn merge_fields( &self, fields: &TemporalFields, additional_fields: &TemporalFields, - context: &mut dyn Any, + context: &mut Self::Context, ) -> TemporalResult; /// Debug name - fn identifier(&self, context: &mut dyn Any) -> TemporalResult; + fn identifier(&self, context: &mut Self::Context) -> TemporalResult; } /// A trait for retrieving an internal calendar slice. @@ -369,7 +373,7 @@ impl CalendarSlot { &self, fields: &mut TemporalFields, overflow: ArithmeticOverflow, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult> { match self { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => { @@ -412,7 +416,7 @@ impl CalendarSlot { &self, fields: &mut TemporalFields, overflow: ArithmeticOverflow, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult> { match self { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => { @@ -440,7 +444,7 @@ impl CalendarSlot { &self, fields: &mut TemporalFields, overflow: ArithmeticOverflow, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult> { match self { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => { @@ -482,7 +486,7 @@ impl CalendarSlot { date: &Date, duration: &Duration, overflow: ArithmeticOverflow, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult> { match self { CalendarSlot::Builtin(_) => { @@ -500,7 +504,7 @@ impl CalendarSlot { one: &Date, two: &Date, largest_unit: TemporalUnit, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult { match self { CalendarSlot::Builtin(_) => { @@ -516,7 +520,7 @@ impl CalendarSlot { pub fn era( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult>> { match self { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(None), @@ -532,7 +536,7 @@ impl CalendarSlot { pub fn era_year( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult> { match self { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(None), @@ -548,7 +552,7 @@ impl CalendarSlot { pub fn year( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult { match self { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(date_like.as_iso_date().year), @@ -564,7 +568,7 @@ impl CalendarSlot { pub fn month( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult { match self { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(date_like.as_iso_date().month), @@ -579,7 +583,7 @@ impl CalendarSlot { pub fn month_code( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult> { match self { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => { @@ -596,7 +600,7 @@ impl CalendarSlot { pub fn day( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult { match self { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(date_like.as_iso_date().day), @@ -611,7 +615,7 @@ impl CalendarSlot { pub fn day_of_week( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult { match self { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => { @@ -628,7 +632,7 @@ impl CalendarSlot { pub fn day_of_year( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult { match self { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(date_like @@ -647,7 +651,7 @@ impl CalendarSlot { pub fn week_of_year( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult { match self { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => { @@ -672,7 +676,7 @@ impl CalendarSlot { pub fn year_of_week( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult { match self { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => { @@ -701,7 +705,7 @@ impl CalendarSlot { pub fn days_in_week( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult { match self { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(7), @@ -716,7 +720,7 @@ impl CalendarSlot { pub fn days_in_month( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult { match self { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => { @@ -734,7 +738,7 @@ impl CalendarSlot { pub fn days_in_year( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult { match self { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => { @@ -751,7 +755,7 @@ impl CalendarSlot { pub fn months_in_year( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult { match self { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(12), @@ -766,7 +770,7 @@ impl CalendarSlot { pub fn in_leap_year( &self, date_like: &CalendarDateLike, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult { match self { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => { @@ -783,7 +787,7 @@ impl CalendarSlot { pub fn fields( &self, fields: Vec, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult> { match self { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(fields), @@ -799,7 +803,7 @@ impl CalendarSlot { &self, fields: &TemporalFields, additional_fields: &TemporalFields, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult { match self { CalendarSlot::Builtin(_) => fields.merge_fields(additional_fields, self), @@ -810,7 +814,7 @@ impl CalendarSlot { } /// Returns the identifier of this calendar slot. - pub fn identifier(&self, context: &mut dyn Any) -> TemporalResult { + pub fn identifier(&self, context: &mut C::Context) -> TemporalResult { match self { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(String::from("iso8601")), CalendarSlot::Builtin(builtin) => Ok(String::from(builtin.debug_name())), @@ -857,25 +861,27 @@ impl IsoDateSlots for () { } } -impl DateTypes<()> for () { - type Date = Date<()>; - type DateTime = DateTime<()>; - type YearMonth = YearMonth<()>; - type MonthDay = MonthDay<()>; -} - /// An empty `CalendarProtocol` implementation on `()`. /// /// # Panics /// /// Attempting to use this empty calendar implementation as a valid calendar is an error and will cause a panic. impl CalendarProtocol for () { - type DateLikes = (); + type Date = Date<()>; + + type DateTime = DateTime<()>; + + type YearMonth = YearMonth<()>; + + type MonthDay = MonthDay<()>; + + type Context = (); + fn date_from_fields( &self, _: &mut TemporalFields, _: ArithmeticOverflow, - _: &mut dyn Any, + (): &mut (), ) -> TemporalResult> { unreachable!(); } @@ -884,7 +890,7 @@ impl CalendarProtocol for () { &self, _: &mut TemporalFields, _: ArithmeticOverflow, - _: &mut dyn Any, + (): &mut (), ) -> TemporalResult> { unreachable!(); } @@ -893,7 +899,7 @@ impl CalendarProtocol for () { &self, _: &mut TemporalFields, _: ArithmeticOverflow, - _: &mut dyn Any, + (): &mut (), ) -> TemporalResult> { unreachable!() } @@ -903,7 +909,7 @@ impl CalendarProtocol for () { _: &Date, _: &Duration, _: ArithmeticOverflow, - _: &mut dyn Any, + (): &mut (), ) -> TemporalResult> { unreachable!(); } @@ -913,7 +919,7 @@ impl CalendarProtocol for () { _: &Date<()>, _: &Date<()>, _: TemporalUnit, - _: &mut dyn Any, + (): &mut (), ) -> TemporalResult { unreachable!(); } @@ -921,72 +927,72 @@ impl CalendarProtocol for () { fn era( &self, _: &CalendarDateLike, - _: &mut dyn Any, + (): &mut (), ) -> TemporalResult>> { unreachable!(); } - fn era_year(&self, _: &CalendarDateLike, _: &mut dyn Any) -> TemporalResult> { + fn era_year(&self, _: &CalendarDateLike, (): &mut ()) -> TemporalResult> { unreachable!(); } - fn year(&self, _: &CalendarDateLike, _: &mut dyn Any) -> TemporalResult { + fn year(&self, _: &CalendarDateLike, (): &mut ()) -> TemporalResult { unreachable!(); } - fn month(&self, _: &CalendarDateLike, _: &mut dyn Any) -> TemporalResult { + fn month(&self, _: &CalendarDateLike, (): &mut ()) -> TemporalResult { unreachable!(); } fn month_code( &self, _: &CalendarDateLike, - _: &mut dyn Any, + (): &mut (), ) -> TemporalResult> { unreachable!(); } - fn day(&self, _: &CalendarDateLike, _: &mut dyn Any) -> TemporalResult { + fn day(&self, _: &CalendarDateLike, (): &mut ()) -> TemporalResult { unreachable!(); } - fn day_of_week(&self, _: &CalendarDateLike, _: &mut dyn Any) -> TemporalResult { + fn day_of_week(&self, _: &CalendarDateLike, (): &mut ()) -> TemporalResult { unreachable!(); } - fn day_of_year(&self, _: &CalendarDateLike, _: &mut dyn Any) -> TemporalResult { + fn day_of_year(&self, _: &CalendarDateLike, (): &mut ()) -> TemporalResult { unreachable!(); } - fn week_of_year(&self, _: &CalendarDateLike, _: &mut dyn Any) -> TemporalResult { + fn week_of_year(&self, _: &CalendarDateLike, (): &mut ()) -> TemporalResult { unreachable!(); } - fn year_of_week(&self, _: &CalendarDateLike, _: &mut dyn Any) -> TemporalResult { + fn year_of_week(&self, _: &CalendarDateLike, (): &mut ()) -> TemporalResult { unreachable!(); } - fn days_in_week(&self, _: &CalendarDateLike, _: &mut dyn Any) -> TemporalResult { + fn days_in_week(&self, _: &CalendarDateLike, (): &mut ()) -> TemporalResult { unreachable!(); } - fn days_in_month(&self, _: &CalendarDateLike, _: &mut dyn Any) -> TemporalResult { + fn days_in_month(&self, _: &CalendarDateLike, (): &mut ()) -> TemporalResult { unreachable!(); } - fn days_in_year(&self, _: &CalendarDateLike, _: &mut dyn Any) -> TemporalResult { + fn days_in_year(&self, _: &CalendarDateLike, (): &mut ()) -> TemporalResult { unreachable!(); } - fn months_in_year(&self, _: &CalendarDateLike, _: &mut dyn Any) -> TemporalResult { + fn months_in_year(&self, _: &CalendarDateLike, (): &mut ()) -> TemporalResult { unreachable!(); } - fn in_leap_year(&self, _: &CalendarDateLike, _: &mut dyn Any) -> TemporalResult { + fn in_leap_year(&self, _: &CalendarDateLike, (): &mut ()) -> TemporalResult { unreachable!(); } - fn fields(&self, _: Vec, _: &mut dyn Any) -> TemporalResult> { + fn fields(&self, _: Vec, (): &mut ()) -> TemporalResult> { unreachable!(); } @@ -994,12 +1000,12 @@ impl CalendarProtocol for () { &self, _: &TemporalFields, _: &TemporalFields, - _: &mut dyn Any, + (): &mut (), ) -> TemporalResult { unreachable!(); } - fn identifier(&self, _: &mut dyn Any) -> TemporalResult { + fn identifier(&self, (): &mut ()) -> TemporalResult { unreachable!(); } } diff --git a/core/temporal/src/components/date.rs b/core/temporal/src/components/date.rs index 0b768035f2..d6c80eb265 100644 --- a/core/temporal/src/components/date.rs +++ b/core/temporal/src/components/date.rs @@ -13,10 +13,10 @@ use crate::{ parser::parse_date_time, TemporalError, TemporalResult, }; -use std::{any::Any, str::FromStr}; +use std::str::FromStr; use super::{ - calendar::{CalendarDateLike, DateTypes, GetCalendarSlot}, + calendar::{CalendarDateLike, GetCalendarSlot}, duration::TimeDuration, }; @@ -42,7 +42,7 @@ impl Date { pub(crate) fn move_relative_date( &self, duration: &Duration, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult<(Self, f64)> { let new_date = self.contextual_add_date(duration, ArithmeticOverflow::Constrain, context)?; @@ -215,117 +215,102 @@ impl Date<()> { // reference count increment. Need to test. impl Date { /// Returns the calendar year value with provided context. - pub fn contextualized_year( - this: &>::Date, - context: &mut dyn Any, - ) -> TemporalResult { + pub fn contextual_year(this: &C::Date, context: &mut C::Context) -> TemporalResult { this.get_calendar() .year(&CalendarDateLike::CustomDate(this.clone()), context) } /// Returns the calendar month value with provided context. - pub fn contextualized_month( - this: &>::Date, - context: &mut dyn Any, - ) -> TemporalResult { + pub fn contextual_month(this: &C::Date, context: &mut C::Context) -> TemporalResult { this.get_calendar() .month(&CalendarDateLike::CustomDate(this.clone()), context) } /// Returns the calendar month code value with provided context. - pub fn contextualized_month_code( - this: &>::Date, - context: &mut dyn Any, + pub fn contextual_month_code( + this: &C::Date, + context: &mut C::Context, ) -> TemporalResult> { this.get_calendar() .month_code(&CalendarDateLike::CustomDate(this.clone()), context) } /// Returns the calendar day value with provided context. - pub fn contextualized_day( - this: &>::Date, - context: &mut dyn Any, - ) -> TemporalResult { + pub fn contextual_day(this: &C::Date, context: &mut C::Context) -> TemporalResult { this.get_calendar() .day(&CalendarDateLike::CustomDate(this.clone()), context) } /// Returns the calendar day of week value with provided context. - pub fn contextualized_day_of_week( - this: &>::Date, - context: &mut dyn Any, - ) -> TemporalResult { + pub fn contextual_day_of_week(this: &C::Date, context: &mut C::Context) -> TemporalResult { this.get_calendar() .day_of_week(&CalendarDateLike::CustomDate(this.clone()), context) } /// Returns the calendar day of year value with provided context. - pub fn contextualized_day_of_year( - this: &>::Date, - context: &mut dyn Any, - ) -> TemporalResult { + pub fn contextual_day_of_year(this: &C::Date, context: &mut C::Context) -> TemporalResult { this.get_calendar() .day_of_year(&CalendarDateLike::CustomDate(this.clone()), context) } /// Returns the calendar week of year value with provided context. - pub fn contextualized_week_of_year( - this: &>::Date, - context: &mut dyn Any, + pub fn contextual_week_of_year( + this: &C::Date, + context: &mut C::Context, ) -> TemporalResult { this.get_calendar() .week_of_year(&CalendarDateLike::CustomDate(this.clone()), context) } /// Returns the calendar year of week value with provided context. - pub fn contextualized_year_of_week( - this: &>::Date, - context: &mut dyn Any, + pub fn contextual_year_of_week( + this: &C::Date, + context: &mut C::Context, ) -> TemporalResult { this.get_calendar() .year_of_week(&CalendarDateLike::CustomDate(this.clone()), context) } /// Returns the calendar days in week value with provided context. - pub fn contextualized_days_in_week( - this: &>::Date, - context: &mut dyn Any, + pub fn contextual_days_in_week( + this: &C::Date, + context: &mut C::Context, ) -> TemporalResult { this.get_calendar() .days_in_week(&CalendarDateLike::CustomDate(this.clone()), context) } /// Returns the calendar days in month value with provided context. - pub fn contextualized_days_in_month( - this: &>::Date, - context: &mut dyn Any, + pub fn contextual_days_in_month( + this: &C::Date, + context: &mut C::Context, ) -> TemporalResult { this.get_calendar() .days_in_month(&CalendarDateLike::CustomDate(this.clone()), context) } /// Returns the calendar days in year value with provided context. - pub fn contextualized_days_in_year( - this: &>::Date, - context: &mut dyn Any, + pub fn contextual_days_in_year( + this: &C::Date, + context: &mut C::Context, ) -> TemporalResult { this.get_calendar() .days_in_year(&CalendarDateLike::CustomDate(this.clone()), context) } /// Returns the calendar months in year value with provided context. - pub fn contextualized_months_in_year( - this: &>::Date, - context: &mut dyn Any, + pub fn contextual_months_in_year( + this: &C::Date, + context: &mut C::Context, ) -> TemporalResult { this.get_calendar() .months_in_year(&CalendarDateLike::CustomDate(this.clone()), context) } /// Returns whether the date is in a leap year for the given calendar with provided context. - pub fn contextualized_in_leap_year( - this: &>::Date, - context: &mut dyn Any, + pub fn contextual_in_leap_year( + this: &C::Date, + context: &mut C::Context, ) -> TemporalResult { this.get_calendar() .in_leap_year(&CalendarDateLike::CustomDate(this.clone()), context) @@ -356,7 +341,7 @@ impl Date { &self, duration: &Duration, overflow: ArithmeticOverflow, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult { // 1. If options is not present, set options to undefined. // 2. If duration.[[Years]] ≠ 0, or duration.[[Months]] ≠ 0, or duration.[[Weeks]] ≠ 0, then @@ -391,18 +376,6 @@ impl Date { Ok(Self::new_unchecked(result, self.calendar().clone())) } - /// Returns the date after adding the given duration to date. - /// - /// Temporal Equivalent: 3.5.13 `AddDate ( calendar, plainDate, duration [ , options [ , dateAdd ] ] )` - #[inline] - pub fn add_date( - &self, - duration: &Duration, - overflow: ArithmeticOverflow, - ) -> TemporalResult { - self.contextual_add_date(duration, overflow, &mut ()) - } - /// Returns a duration representing the difference between the dates one and two with a provided context. /// /// Temporal Equivalent: 3.5.6 `DifferenceDate ( calendar, one, two, options )` @@ -411,7 +384,7 @@ impl Date { &self, other: &Self, largest_unit: TemporalUnit, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult { if self.iso.year == other.iso.year && self.iso.month == other.iso.month @@ -433,18 +406,6 @@ impl Date { self.calendar() .date_until(self, other, largest_unit, context) } - - /// Returns a duration representing the difference between the dates one and two. - /// - /// Temporal Equivalent: 3.5.6 `DifferenceDate ( calendar, one, two, options )` - #[inline] - pub fn difference_date( - &self, - other: &Self, - largest_unit: TemporalUnit, - ) -> TemporalResult { - self.contextual_difference_date(other, largest_unit, &mut ()) - } } // ==== Trait impls ==== diff --git a/core/temporal/src/components/datetime.rs b/core/temporal/src/components/datetime.rs index 1dfc69f3f9..1a5197c6fb 100644 --- a/core/temporal/src/components/datetime.rs +++ b/core/temporal/src/components/datetime.rs @@ -11,10 +11,10 @@ use crate::{ TemporalError, TemporalResult, }; -use std::{any::Any, str::FromStr}; +use std::str::FromStr; use tinystr::TinyAsciiStr; -use super::calendar::{CalendarDateLike, DateTypes, GetCalendarSlot}; +use super::calendar::{CalendarDateLike, GetCalendarSlot}; /// The native Rust implementation of `Temporal.PlainDateTime` #[derive(Debug, Default, Clone)] @@ -248,117 +248,108 @@ impl DateTime<()> { impl DateTime { /// Returns the calendar year value with provided context. - pub fn contextualized_year( - this: &>::DateTime, - context: &mut dyn Any, - ) -> TemporalResult { + pub fn contextual_year(this: &C::DateTime, context: &mut C::Context) -> TemporalResult { this.get_calendar() .year(&CalendarDateLike::CustomDateTime(this.clone()), context) } /// Returns the calendar month value with provided context. - pub fn contextualized_month( - this: &>::DateTime, - context: &mut dyn Any, - ) -> TemporalResult { + pub fn contextual_month(this: &C::DateTime, context: &mut C::Context) -> TemporalResult { this.get_calendar() .month(&CalendarDateLike::CustomDateTime(this.clone()), context) } /// Returns the calendar month code value with provided context. - pub fn contextualized_month_code( - this: &>::DateTime, - context: &mut dyn Any, + pub fn contextual_month_code( + this: &C::DateTime, + context: &mut C::Context, ) -> TemporalResult> { this.get_calendar() .month_code(&CalendarDateLike::CustomDateTime(this.clone()), context) } /// Returns the calendar day value with provided context. - pub fn contextualized_day( - this: &>::DateTime, - context: &mut dyn Any, - ) -> TemporalResult { + pub fn contextual_day(this: &C::DateTime, context: &mut C::Context) -> TemporalResult { this.get_calendar() .day(&CalendarDateLike::CustomDateTime(this.clone()), context) } /// Returns the calendar day of week value with provided context. - pub fn contextualized_day_of_week( - this: &>::DateTime, - context: &mut dyn Any, + pub fn contextual_day_of_week( + this: &C::DateTime, + context: &mut C::Context, ) -> TemporalResult { this.get_calendar() .day_of_week(&CalendarDateLike::CustomDateTime(this.clone()), context) } /// Returns the calendar day of year value with provided context. - pub fn contextualized_day_of_year( - this: &>::DateTime, - context: &mut dyn Any, + pub fn contextual_day_of_year( + this: &C::DateTime, + context: &mut C::Context, ) -> TemporalResult { this.get_calendar() .day_of_year(&CalendarDateLike::CustomDateTime(this.clone()), context) } /// Returns the calendar week of year value with provided context. - pub fn contextualized_week_of_year( - this: &>::DateTime, - context: &mut dyn Any, + pub fn contextual_week_of_year( + this: &C::DateTime, + context: &mut C::Context, ) -> TemporalResult { this.get_calendar() .week_of_year(&CalendarDateLike::CustomDateTime(this.clone()), context) } /// Returns the calendar year of week value with provided context. - pub fn contextualized_year_of_week( - this: &>::DateTime, - context: &mut dyn Any, + pub fn contextual_year_of_week( + this: &C::DateTime, + context: &mut C::Context, ) -> TemporalResult { this.get_calendar() .year_of_week(&CalendarDateLike::CustomDateTime(this.clone()), context) } /// Returns the calendar days in week value with provided context. - pub fn contextualized_days_in_week( - this: &>::DateTime, - context: &mut dyn Any, + pub fn contextual_days_in_week( + this: &C::DateTime, + context: &mut C::Context, ) -> TemporalResult { this.get_calendar() .days_in_week(&CalendarDateLike::CustomDateTime(this.clone()), context) } /// Returns the calendar days in month value with provided context. - pub fn contextualized_days_in_month( - this: &>::DateTime, - context: &mut dyn Any, + pub fn contextual_days_in_month( + this: &C::DateTime, + context: &mut C::Context, ) -> TemporalResult { this.get_calendar() .days_in_month(&CalendarDateLike::CustomDateTime(this.clone()), context) } /// Returns the calendar days in year value with provided context. - pub fn contextualized_days_in_year( - this: &>::DateTime, - context: &mut dyn Any, + pub fn contextual_days_in_year( + this: &C::DateTime, + context: &mut C::Context, ) -> TemporalResult { this.get_calendar() .days_in_year(&CalendarDateLike::CustomDateTime(this.clone()), context) } /// Returns the calendar months in year value with provided context. - pub fn contextualized_months_in_year( - this: &>::DateTime, - context: &mut dyn Any, + pub fn contextual_months_in_year( + this: &C::DateTime, + context: &mut C::Context, ) -> TemporalResult { this.get_calendar() .months_in_year(&CalendarDateLike::CustomDateTime(this.clone()), context) } /// Returns whether the date is in a leap year for the given calendar with provided context. - pub fn contextualized_in_leap_year( - this: &>::DateTime, - context: &mut dyn Any, + pub fn contextual_in_leap_year( + this: &C::DateTime, + context: &mut C::Context, ) -> TemporalResult { this.get_calendar() .in_leap_year(&CalendarDateLike::CustomDateTime(this.clone()), context) diff --git a/core/temporal/src/components/duration.rs b/core/temporal/src/components/duration.rs index 8486064bcf..13205dc465 100644 --- a/core/temporal/src/components/duration.rs +++ b/core/temporal/src/components/duration.rs @@ -6,7 +6,7 @@ use crate::{ parser::{duration::parse_duration, Cursor}, TemporalError, TemporalResult, }; -use std::{any::Any, str::FromStr}; +use std::str::FromStr; use super::{calendar::CalendarProtocol, tz::TzProtocol}; @@ -370,7 +370,7 @@ impl Duration { &self, largest_unit: TemporalUnit, plain_relative_to: Option<&Date>, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult { // 1. Let allZero be false. // 2. If years = 0, and months = 0, and weeks = 0, and days = 0, set allZero to true. @@ -576,7 +576,7 @@ impl Duration { &self, largest_unit: TemporalUnit, plain_relative_to: Option<&Date>, - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult { let mut result = self.date; @@ -816,7 +816,7 @@ impl Duration { Option<&ZonedDateTime>, Option<&DateTime>, ), - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult<(Self, f64)> { match unit { TemporalUnit::Year | TemporalUnit::Month | TemporalUnit::Week | TemporalUnit::Day => { diff --git a/core/temporal/src/components/duration/date.rs b/core/temporal/src/components/duration/date.rs index 2fec74995d..9f83097928 100644 --- a/core/temporal/src/components/duration/date.rs +++ b/core/temporal/src/components/duration/date.rs @@ -9,8 +9,6 @@ use crate::{ utils, TemporalError, TemporalResult, NS_PER_DAY, }; -use std::any::Any; - /// `DateDuration` represents the [date duration record][spec] of the `Duration.` /// /// These fields are laid out in the [Temporal Proposal][field spec] as 64-bit floating point numbers. @@ -147,7 +145,7 @@ impl DateDuration { Option<&ZonedDateTime>, Option<&DateTime>, ), - context: &mut dyn Any, + context: &mut C::Context, ) -> TemporalResult<(Self, f64)> { // 1. If plainRelativeTo is not present, set plainRelativeTo to undefined. let plain_relative_to = relative_targets.0; diff --git a/core/temporal/src/components/tz.rs b/core/temporal/src/components/tz.rs index 6a83f3fedf..4deb4b0674 100644 --- a/core/temporal/src/components/tz.rs +++ b/core/temporal/src/components/tz.rs @@ -1,7 +1,5 @@ //! This module implements the Temporal `TimeZone` and components. -use std::any::Any; - use num_bigint::BigInt; use num_traits::ToPrimitive; @@ -18,12 +16,15 @@ pub const TIME_ZONE_PROPERTIES: [&str; 3] = /// The Time Zone Protocol that must be implemented for time zones. pub trait TzProtocol: Clone { + /// The context passed to every method of the `TzProtocol`. + type Context; /// Get the Offset nanoseconds for this `TimeZone` - fn get_offset_nanos_for(&self, context: &mut dyn Any) -> TemporalResult; + fn get_offset_nanos_for(&self, context: &mut Self::Context) -> TemporalResult; /// Get the possible Instant for this `TimeZone` - fn get_possible_instant_for(&self, context: &mut dyn Any) -> TemporalResult>; // TODO: Implement Instant + fn get_possible_instant_for(&self, context: &mut Self::Context) + -> TemporalResult>; // TODO: Implement Instant /// Get the `TimeZone`'s identifier. - fn id(&self, context: &mut dyn Any) -> TemporalResult; + fn id(&self, context: &mut Self::Context) -> TemporalResult; } /// A Temporal `TimeZone`. @@ -57,7 +58,7 @@ impl TimeZoneSlot { &self, instant: &Instant, calendar: &CalendarSlot, - context: &mut dyn Any, + context: &mut Z::Context, ) -> TemporalResult> { let nanos = self.get_offset_nanos_for(context)?; DateTime::from_instant(instant, nanos.to_f64().unwrap_or(0.0), calendar.clone()) @@ -66,7 +67,7 @@ impl TimeZoneSlot { impl TimeZoneSlot { /// Get the offset for this current `TimeZoneSlot`. - pub fn get_offset_nanos_for(&self, context: &mut dyn Any) -> TemporalResult { + pub fn get_offset_nanos_for(&self, context: &mut Z::Context) -> TemporalResult { // 1. Let timeZone be the this value. // 2. Perform ? RequireInternalSlot(timeZone, [[InitializedTemporalTimeZone]]). // 3. Set instant to ? ToTemporalInstant(instant). @@ -85,12 +86,15 @@ impl TimeZoneSlot { } /// Get the possible `Instant`s for this `TimeZoneSlot`. - pub fn get_possible_instant_for(&self, _context: &mut dyn Any) -> TemporalResult> { + pub fn get_possible_instant_for( + &self, + _context: &mut Z::Context, + ) -> TemporalResult> { Err(TemporalError::general("Not yet implemented.")) } /// Returns the current `TimeZoneSlot`'s identifier. - pub fn id(&self, context: &mut dyn Any) -> TemporalResult { + pub fn id(&self, context: &mut Z::Context) -> TemporalResult { match self { Self::Tz(_) => Err(TemporalError::range().with_message("Not yet implemented.")), // TODO: Implement Display for Time Zone. Self::Protocol(tz) => tz.id(context), @@ -99,15 +103,16 @@ impl TimeZoneSlot { } impl TzProtocol for () { - fn get_offset_nanos_for(&self, _: &mut dyn Any) -> TemporalResult { + type Context = (); + fn get_offset_nanos_for(&self, (): &mut ()) -> TemporalResult { unreachable!() } - fn get_possible_instant_for(&self, _: &mut dyn Any) -> TemporalResult> { + fn get_possible_instant_for(&self, (): &mut ()) -> TemporalResult> { unreachable!() } - fn id(&self, _: &mut dyn Any) -> TemporalResult { + fn id(&self, (): &mut ()) -> TemporalResult { Ok("() TimeZone".to_owned()) } } diff --git a/core/temporal/src/components/zoneddatetime.rs b/core/temporal/src/components/zoneddatetime.rs index 489efd1f6d..04d72941af 100644 --- a/core/temporal/src/components/zoneddatetime.rs +++ b/core/temporal/src/components/zoneddatetime.rs @@ -12,8 +12,6 @@ use crate::{ TemporalResult, }; -use core::any::Any; - use super::tz::TzProtocol; /// The native Rust implementation of `Temporal.ZonedDateTime`. @@ -98,24 +96,21 @@ impl ZonedDateTime { // ==== Context based API ==== -impl ZonedDateTime { +impl ZonedDateTime +where + C: CalendarProtocol, +{ /// Returns the `year` value for this `ZonedDateTime`. #[inline] - pub fn contextual_year(&self, context: &mut dyn Any) -> TemporalResult { + pub fn contextual_year(&self, context: &mut C::Context) -> TemporalResult { let dt = self .tz .get_datetime_for(&self.instant, &self.calendar, context)?; self.calendar.year(&CalendarDateLike::DateTime(dt), context) } - /// Returns the `year` value for this `ZonedDateTime`. - #[inline] - pub fn year(&self) -> TemporalResult { - self.contextual_year(&mut ()) - } - /// Returns the `month` value for this `ZonedDateTime`. - pub fn contextual_month(&self, context: &mut dyn Any) -> TemporalResult { + pub fn contextual_month(&self, context: &mut C::Context) -> TemporalResult { let dt = self .tz .get_datetime_for(&self.instant, &self.calendar, context)?; @@ -123,14 +118,8 @@ impl ZonedDateTime { .month(&CalendarDateLike::DateTime(dt), context) } - /// Returns the `month` value for this `ZonedDateTime`. - #[inline] - pub fn month(&self) -> TemporalResult { - self.contextual_month(&mut ()) - } - /// Returns the `monthCode` value for this `ZonedDateTime`. - pub fn contextual_month_code(&self, context: &mut dyn Any) -> TemporalResult { + pub fn contextual_month_code(&self, context: &mut C::Context) -> TemporalResult { let dt = self .tz .get_datetime_for(&self.instant, &self.calendar, context)?; @@ -138,102 +127,61 @@ impl ZonedDateTime { .month_code(&CalendarDateLike::DateTime(dt), context) } - /// Returns the `monthCode` value for this `ZonedDateTime`. - #[inline] - pub fn month_code(&self) -> TemporalResult { - self.contextual_month_code(&mut ()) - } - /// Returns the `day` value for this `ZonedDateTime`. - pub fn contextual_day(&self, context: &mut dyn Any) -> TemporalResult { + pub fn contextual_day(&self, context: &mut C::Context) -> TemporalResult { let dt = self .tz .get_datetime_for(&self.instant, &self.calendar, context)?; self.calendar.day(&CalendarDateLike::DateTime(dt), context) } - /// Returns the `day` value for this `ZonedDateTime`. - pub fn day(&self) -> TemporalResult { - self.contextual_day(&mut ()) - } - /// Returns the `hour` value for this `ZonedDateTime`. - pub fn contextual_hour(&self, context: &mut dyn Any) -> TemporalResult { + pub fn contextual_hour(&self, context: &mut C::Context) -> TemporalResult { let dt = self .tz .get_datetime_for(&self.instant, &self.calendar, context)?; Ok(dt.hour()) } - /// Returns the `hour` value for this `ZonedDateTime`. - pub fn hour(&self) -> TemporalResult { - self.contextual_hour(&mut ()) - } - /// Returns the `minute` value for this `ZonedDateTime`. - pub fn contextual_minute(&self, context: &mut dyn Any) -> TemporalResult { + pub fn contextual_minute(&self, context: &mut C::Context) -> TemporalResult { let dt = self .tz .get_datetime_for(&self.instant, &self.calendar, context)?; Ok(dt.minute()) } - /// Returns the `minute` value for this `ZonedDateTime`. - pub fn minute(&self) -> TemporalResult { - self.contextual_minute(&mut ()) - } - /// Returns the `second` value for this `ZonedDateTime`. - pub fn contextual_second(&self, context: &mut dyn Any) -> TemporalResult { + pub fn contextual_second(&self, context: &mut C::Context) -> TemporalResult { let dt = self .tz .get_datetime_for(&self.instant, &self.calendar, context)?; Ok(dt.second()) } - /// Returns the `second` value for this `ZonedDateTime`. - pub fn second(&self) -> TemporalResult { - self.contextual_second(&mut ()) - } - /// Returns the `millisecond` value for this `ZonedDateTime`. - pub fn contextual_millisecond(&self, context: &mut dyn Any) -> TemporalResult { + pub fn contextual_millisecond(&self, context: &mut C::Context) -> TemporalResult { let dt = self .tz .get_datetime_for(&self.instant, &self.calendar, context)?; Ok(dt.millisecond()) } - /// Returns the `millisecond` value for this `ZonedDateTime`. - pub fn millisecond(&self) -> TemporalResult { - self.contextual_millisecond(&mut ()) - } - /// Returns the `microsecond` value for this `ZonedDateTime`. - pub fn contextual_microsecond(&self, context: &mut dyn Any) -> TemporalResult { + pub fn contextual_microsecond(&self, context: &mut C::Context) -> TemporalResult { let dt = self .tz .get_datetime_for(&self.instant, &self.calendar, context)?; Ok(dt.millisecond()) } - /// Returns the `microsecond` value for this `ZonedDateTime`. - pub fn microsecond(&self) -> TemporalResult { - self.contextual_microsecond(&mut ()) - } - /// Returns the `nanosecond` value for this `ZonedDateTime`. - pub fn contextual_nanosecond(&self, context: &mut dyn Any) -> TemporalResult { + pub fn contextual_nanosecond(&self, context: &mut C::Context) -> TemporalResult { let dt = self .tz .get_datetime_for(&self.instant, &self.calendar, context)?; Ok(dt.nanosecond()) } - - /// Returns the `nanosecond` value for this `ZonedDateTime`. - pub fn nanosecond(&self) -> TemporalResult { - self.contextual_nanosecond(&mut ()) - } } #[cfg(test)] @@ -259,12 +207,12 @@ mod tests { ) .unwrap(); - assert_eq!(zdt.year().unwrap(), 2023); - assert_eq!(zdt.month().unwrap(), 11); - assert_eq!(zdt.day().unwrap(), 30); - assert_eq!(zdt.hour().unwrap(), 1); - assert_eq!(zdt.minute().unwrap(), 49); - assert_eq!(zdt.second().unwrap(), 12); + assert_eq!(zdt.contextual_year(&mut ()).unwrap(), 2023); + assert_eq!(zdt.contextual_month(&mut ()).unwrap(), 11); + assert_eq!(zdt.contextual_day(&mut ()).unwrap(), 30); + assert_eq!(zdt.contextual_hour(&mut ()).unwrap(), 1); + assert_eq!(zdt.contextual_minute(&mut ()).unwrap(), 49); + assert_eq!(zdt.contextual_second(&mut ()).unwrap(), 12); let zdt_minus_five = ZonedDateTime::<(), ()>::new( nov_30_2023_utc, @@ -276,11 +224,11 @@ mod tests { ) .unwrap(); - assert_eq!(zdt_minus_five.year().unwrap(), 2023); - assert_eq!(zdt_minus_five.month().unwrap(), 11); - assert_eq!(zdt_minus_five.day().unwrap(), 29); - assert_eq!(zdt_minus_five.hour().unwrap(), 20); - assert_eq!(zdt_minus_five.minute().unwrap(), 49); - assert_eq!(zdt_minus_five.second().unwrap(), 12); + assert_eq!(zdt_minus_five.contextual_year(&mut ()).unwrap(), 2023); + assert_eq!(zdt_minus_five.contextual_month(&mut ()).unwrap(), 11); + assert_eq!(zdt_minus_five.contextual_day(&mut ()).unwrap(), 29); + assert_eq!(zdt_minus_five.contextual_hour(&mut ()).unwrap(), 20); + assert_eq!(zdt_minus_five.contextual_minute(&mut ()).unwrap(), 49); + assert_eq!(zdt_minus_five.contextual_second(&mut ()).unwrap(), 12); } }