Browse Source

Simplify Temporal APIs (#3653)

* Simplify Temporal APIs

* cargo fmt

* Unroll deletion of context-free API
pull/3655/head
José Julián Espina 9 months ago committed by GitHub
parent
commit
0f33b98e75
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 136
      core/engine/src/builtins/temporal/calendar/object.rs
  2. 30
      core/engine/src/builtins/temporal/plain_date/mod.rs
  3. 26
      core/engine/src/builtins/temporal/plain_date_time/mod.rs
  4. 22
      core/engine/src/builtins/temporal/time_zone/custom.rs
  5. 198
      core/temporal/src/components/calendar.rs
  6. 107
      core/temporal/src/components/date.rs
  7. 79
      core/temporal/src/components/datetime.rs
  8. 8
      core/temporal/src/components/duration.rs
  9. 4
      core/temporal/src/components/duration/date.rs
  10. 29
      core/temporal/src/components/tz.rs
  11. 104
      core/temporal/src/components/zoneddatetime.rs

136
core/engine/src/builtins/temporal/calendar/object.rs

@ -12,12 +12,11 @@ use crate::{
property::PropertyKey, property::PropertyKey,
Context, JsObject, JsString, JsValue, Context, JsObject, JsString, JsValue,
}; };
use std::any::Any;
use boa_macros::utf16; use boa_macros::utf16;
use boa_temporal::{ use boa_temporal::{
components::{ components::{
calendar::{CalendarDateLike, CalendarProtocol, DateTypes}, calendar::{CalendarDateLike, CalendarProtocol},
Date, Duration, MonthDay, YearMonth, Date, Duration, MonthDay, YearMonth,
}, },
options::ArithmeticOverflow, options::ArithmeticOverflow,
@ -29,29 +28,18 @@ use plain_date_time::PlainDateTime;
use plain_month_day::PlainMonthDay; use plain_month_day::PlainMonthDay;
use plain_year_month::PlainYearMonth; use plain_year_month::PlainYearMonth;
/// The custom data types for a Custom `JsObject` Calendar. impl CalendarProtocol for JsObject {
#[derive(Debug, Clone, Copy)]
pub struct CustomDateLikes;
impl DateTypes<JsObject> for CustomDateLikes {
type Date = JsObject<PlainDate>; type Date = JsObject<PlainDate>;
type DateTime = JsObject<PlainDateTime>; type DateTime = JsObject<PlainDateTime>;
type YearMonth = JsObject<PlainYearMonth>; type YearMonth = JsObject<PlainYearMonth>;
type MonthDay = JsObject<PlainMonthDay>; type MonthDay = JsObject<PlainMonthDay>;
} type Context = Context;
impl CalendarProtocol for JsObject {
type DateLikes = CustomDateLikes;
fn date_from_fields( fn date_from_fields(
&self, &self,
fields: &mut TemporalFields, fields: &mut TemporalFields,
overflow: ArithmeticOverflow, overflow: ArithmeticOverflow,
context: &mut dyn Any, context: &mut Context,
) -> TemporalResult<Date<Self>> { ) -> TemporalResult<Date<Self>> {
let context = context
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomCalendar.");
let method = self let method = self
.get(utf16!("dateFromFields"), context) .get(utf16!("dateFromFields"), context)
.expect("method must exist on a object that implements the CalendarProtocol."); .expect("method must exist on a object that implements the CalendarProtocol.");
@ -97,12 +85,8 @@ impl CalendarProtocol for JsObject {
&self, &self,
fields: &mut TemporalFields, fields: &mut TemporalFields,
overflow: ArithmeticOverflow, overflow: ArithmeticOverflow,
context: &mut dyn Any, context: &mut Context,
) -> TemporalResult<YearMonth<JsObject>> { ) -> TemporalResult<YearMonth<JsObject>> {
let context = context
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomCalendar.");
let method = self let method = self
.get(utf16!("yearMonthFromFields"), context) .get(utf16!("yearMonthFromFields"), context)
.expect("method must exist on a object that implements the CalendarProtocol."); .expect("method must exist on a object that implements the CalendarProtocol.");
@ -150,12 +134,8 @@ impl CalendarProtocol for JsObject {
&self, &self,
fields: &mut TemporalFields, fields: &mut TemporalFields,
overflow: ArithmeticOverflow, overflow: ArithmeticOverflow,
context: &mut dyn Any, context: &mut Context,
) -> TemporalResult<MonthDay<JsObject>> { ) -> TemporalResult<MonthDay<JsObject>> {
let context = context
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomCalendar.");
let method = self let method = self
.get(utf16!("yearMonthFromFields"), context) .get(utf16!("yearMonthFromFields"), context)
.expect("method must exist on a object that implements the CalendarProtocol."); .expect("method must exist on a object that implements the CalendarProtocol.");
@ -204,7 +184,7 @@ impl CalendarProtocol for JsObject {
_date: &Date<JsObject>, _date: &Date<JsObject>,
_duration: &Duration, _duration: &Duration,
_overflow: ArithmeticOverflow, _overflow: ArithmeticOverflow,
_context: &mut dyn Any, _context: &mut Context,
) -> TemporalResult<Date<JsObject>> { ) -> TemporalResult<Date<JsObject>> {
// TODO // TODO
Err(TemporalError::general("Not yet implemented.")) Err(TemporalError::general("Not yet implemented."))
@ -215,7 +195,7 @@ impl CalendarProtocol for JsObject {
_one: &Date<JsObject>, _one: &Date<JsObject>,
_two: &Date<JsObject>, _two: &Date<JsObject>,
_largest_unit: boa_temporal::options::TemporalUnit, _largest_unit: boa_temporal::options::TemporalUnit,
_context: &mut dyn Any, _context: &mut Context,
) -> TemporalResult<Duration> { ) -> TemporalResult<Duration> {
// TODO // TODO
Err(TemporalError::general("Not yet implemented.")) Err(TemporalError::general("Not yet implemented."))
@ -224,7 +204,7 @@ impl CalendarProtocol for JsObject {
fn era( fn era(
&self, &self,
_: &CalendarDateLike<JsObject>, _: &CalendarDateLike<JsObject>,
_: &mut dyn Any, _: &mut Context,
) -> TemporalResult<Option<TinyAsciiStr<16>>> { ) -> TemporalResult<Option<TinyAsciiStr<16>>> {
// Return undefined as custom calendars do not implement -> Currently. // Return undefined as custom calendars do not implement -> Currently.
Ok(None) Ok(None)
@ -233,7 +213,7 @@ impl CalendarProtocol for JsObject {
fn era_year( fn era_year(
&self, &self,
_: &CalendarDateLike<JsObject>, _: &CalendarDateLike<JsObject>,
_: &mut dyn Any, _: &mut Context,
) -> TemporalResult<Option<i32>> { ) -> TemporalResult<Option<i32>> {
// Return undefined as custom calendars do not implement -> Currently. // Return undefined as custom calendars do not implement -> Currently.
Ok(None) Ok(None)
@ -242,12 +222,8 @@ impl CalendarProtocol for JsObject {
fn year( fn year(
&self, &self,
date_like: &CalendarDateLike<JsObject>, date_like: &CalendarDateLike<JsObject>,
context: &mut dyn Any, context: &mut Context,
) -> TemporalResult<i32> { ) -> TemporalResult<i32> {
let context = context
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomCalendar.");
let date_like = date_like_to_object(date_like, context)?; let date_like = date_like_to_object(date_like, context)?;
let method = self let method = self
@ -288,12 +264,8 @@ impl CalendarProtocol for JsObject {
fn month( fn month(
&self, &self,
date_like: &CalendarDateLike<JsObject>, date_like: &CalendarDateLike<JsObject>,
context: &mut dyn Any, context: &mut Context,
) -> TemporalResult<u8> { ) -> TemporalResult<u8> {
let context = context
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomCalendar.");
let date_like = date_like_to_object(date_like, context)?; let date_like = date_like_to_object(date_like, context)?;
let method = self let method = self
@ -334,12 +306,8 @@ impl CalendarProtocol for JsObject {
fn month_code( fn month_code(
&self, &self,
date_like: &CalendarDateLike<JsObject>, date_like: &CalendarDateLike<JsObject>,
context: &mut dyn Any, context: &mut Context,
) -> TemporalResult<TinyAsciiStr<4>> { ) -> TemporalResult<TinyAsciiStr<4>> {
let context = context
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomCalendar.");
let date_like = date_like_to_object(date_like, context)?; let date_like = date_like_to_object(date_like, context)?;
let method = self let method = self
@ -365,12 +333,8 @@ impl CalendarProtocol for JsObject {
fn day( fn day(
&self, &self,
date_like: &CalendarDateLike<JsObject>, date_like: &CalendarDateLike<JsObject>,
context: &mut dyn Any, context: &mut Context,
) -> TemporalResult<u8> { ) -> TemporalResult<u8> {
let context = context
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomCalendar.");
let date_like = date_like_to_object(date_like, context)?; let date_like = date_like_to_object(date_like, context)?;
let method = self let method = self
@ -411,12 +375,8 @@ impl CalendarProtocol for JsObject {
fn day_of_week( fn day_of_week(
&self, &self,
date_like: &CalendarDateLike<JsObject>, date_like: &CalendarDateLike<JsObject>,
context: &mut dyn Any, context: &mut Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
let context = context
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomCalendar.");
let date_like = date_like_to_object(date_like, context)?; let date_like = date_like_to_object(date_like, context)?;
let method = self let method = self
@ -459,12 +419,8 @@ impl CalendarProtocol for JsObject {
fn day_of_year( fn day_of_year(
&self, &self,
date_like: &CalendarDateLike<JsObject>, date_like: &CalendarDateLike<JsObject>,
context: &mut dyn Any, context: &mut Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
let context = context
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomCalendar.");
let date_like = date_like_to_object(date_like, context)?; let date_like = date_like_to_object(date_like, context)?;
let method = self let method = self
@ -507,12 +463,8 @@ impl CalendarProtocol for JsObject {
fn week_of_year( fn week_of_year(
&self, &self,
date_like: &CalendarDateLike<JsObject>, date_like: &CalendarDateLike<JsObject>,
context: &mut dyn Any, context: &mut Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
let context = context
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomCalendar.");
let date_like = date_like_to_object(date_like, context)?; let date_like = date_like_to_object(date_like, context)?;
let method = self let method = self
@ -555,12 +507,8 @@ impl CalendarProtocol for JsObject {
fn year_of_week( fn year_of_week(
&self, &self,
date_like: &CalendarDateLike<JsObject>, date_like: &CalendarDateLike<JsObject>,
context: &mut dyn Any, context: &mut Context,
) -> TemporalResult<i32> { ) -> TemporalResult<i32> {
let context = context
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomCalendar.");
let date_like = date_like_to_object(date_like, context)?; let date_like = date_like_to_object(date_like, context)?;
let method = self let method = self
@ -596,12 +544,8 @@ impl CalendarProtocol for JsObject {
fn days_in_week( fn days_in_week(
&self, &self,
date_like: &CalendarDateLike<JsObject>, date_like: &CalendarDateLike<JsObject>,
context: &mut dyn Any, context: &mut Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
let context = context
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomCalendar.");
let date_like = date_like_to_object(date_like, context)?; let date_like = date_like_to_object(date_like, context)?;
let method = self let method = self
@ -644,12 +588,8 @@ impl CalendarProtocol for JsObject {
fn days_in_month( fn days_in_month(
&self, &self,
date_like: &CalendarDateLike<JsObject>, date_like: &CalendarDateLike<JsObject>,
context: &mut dyn Any, context: &mut Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
let context = context
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomCalendar.");
let date_like = date_like_to_object(date_like, context)?; let date_like = date_like_to_object(date_like, context)?;
let method = self let method = self
@ -693,12 +633,8 @@ impl CalendarProtocol for JsObject {
fn days_in_year( fn days_in_year(
&self, &self,
date_like: &CalendarDateLike<JsObject>, date_like: &CalendarDateLike<JsObject>,
context: &mut dyn Any, context: &mut Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
let context = context
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomCalendar.");
let date_like = date_like_to_object(date_like, context)?; let date_like = date_like_to_object(date_like, context)?;
let method = self let method = self
@ -741,12 +677,8 @@ impl CalendarProtocol for JsObject {
fn months_in_year( fn months_in_year(
&self, &self,
date_like: &CalendarDateLike<JsObject>, date_like: &CalendarDateLike<JsObject>,
context: &mut dyn Any, context: &mut Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
let context = context
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomCalendar.");
let date_like = date_like_to_object(date_like, context)?; let date_like = date_like_to_object(date_like, context)?;
let method = self let method = self
@ -791,12 +723,8 @@ impl CalendarProtocol for JsObject {
fn in_leap_year( fn in_leap_year(
&self, &self,
date_like: &CalendarDateLike<JsObject>, date_like: &CalendarDateLike<JsObject>,
context: &mut dyn Any, context: &mut Context,
) -> TemporalResult<bool> { ) -> TemporalResult<bool> {
let context = context
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomCalendar.");
let date_like = date_like_to_object(date_like, context)?; let date_like = date_like_to_object(date_like, context)?;
let method = self let method = self
@ -818,11 +746,7 @@ impl CalendarProtocol for JsObject {
Ok(result) Ok(result)
} }
fn fields(&self, fields: Vec<String>, context: &mut dyn Any) -> TemporalResult<Vec<String>> { fn fields(&self, fields: Vec<String>, context: &mut Context) -> TemporalResult<Vec<String>> {
let context = context
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomCalendar.");
let fields_js = Array::create_array_from_list( let fields_js = Array::create_array_from_list(
fields.iter().map(|s| JsString::from(s.clone()).into()), fields.iter().map(|s| JsString::from(s.clone()).into()),
context, context,
@ -867,12 +791,8 @@ impl CalendarProtocol for JsObject {
&self, &self,
fields: &TemporalFields, fields: &TemporalFields,
additional_fields: &TemporalFields, additional_fields: &TemporalFields,
context: &mut dyn Any, context: &mut Context,
) -> TemporalResult<TemporalFields> { ) -> TemporalResult<TemporalFields> {
let context = context
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomCalendar.");
let fields = JsObject::from_temporal_fields(fields, context) let fields = JsObject::from_temporal_fields(fields, context)
.map_err(|e| TemporalError::general(e.to_string()))?; .map_err(|e| TemporalError::general(e.to_string()))?;
let add_fields = JsObject::from_temporal_fields(additional_fields, context) 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())) object_to_temporal_fields(&o, context).map_err(|e| TemporalError::general(e.to_string()))
} }
fn identifier(&self, context: &mut dyn Any) -> TemporalResult<String> { fn identifier(&self, context: &mut Context) -> TemporalResult<String> {
let context = context
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomCalendar.");
let identifier = self let identifier = self
.__get__( .__get__(
&PropertyKey::from(utf16!("id")), &PropertyKey::from(utf16!("id")),

30
core/engine/src/builtins/temporal/plain_date/mod.rs

@ -284,7 +284,7 @@ impl PlainDate {
.into()); .into());
}; };
Ok(InnerDate::<JsObject>::contextualized_year(&date, context)?.into()) Ok(InnerDate::<JsObject>::contextual_year(&date, context)?.into())
} }
/// 3.3.5 get `Temporal.PlainDate.prototype.month` /// 3.3.5 get `Temporal.PlainDate.prototype.month`
@ -299,7 +299,7 @@ impl PlainDate {
.into()); .into());
}; };
Ok(InnerDate::<JsObject>::contextualized_month(&date, context)?.into()) Ok(InnerDate::<JsObject>::contextual_month(&date, context)?.into())
} }
/// 3.3.6 get Temporal.PlainDate.prototype.monthCode /// 3.3.6 get Temporal.PlainDate.prototype.monthCode
@ -314,10 +314,10 @@ impl PlainDate {
.into()); .into());
}; };
Ok(JsString::from( Ok(
InnerDate::<JsObject>::contextualized_month_code(&date, context)?.as_str(), JsString::from(InnerDate::<JsObject>::contextual_month_code(&date, context)?.as_str())
.into(),
) )
.into())
} }
/// 3.3.7 get `Temporal.PlainDate.prototype.day` /// 3.3.7 get `Temporal.PlainDate.prototype.day`
@ -332,7 +332,7 @@ impl PlainDate {
.into()); .into());
}; };
Ok(InnerDate::<JsObject>::contextualized_day(&date, context)?.into()) Ok(InnerDate::<JsObject>::contextual_day(&date, context)?.into())
} }
/// 3.3.8 get `Temporal.PlainDate.prototype.dayOfWeek` /// 3.3.8 get `Temporal.PlainDate.prototype.dayOfWeek`
@ -347,7 +347,7 @@ impl PlainDate {
.into()); .into());
}; };
Ok(InnerDate::<JsObject>::contextualized_day_of_week(&date, context)?.into()) Ok(InnerDate::<JsObject>::contextual_day_of_week(&date, context)?.into())
} }
/// 3.3.9 get `Temporal.PlainDate.prototype.dayOfYear` /// 3.3.9 get `Temporal.PlainDate.prototype.dayOfYear`
@ -362,7 +362,7 @@ impl PlainDate {
.into()); .into());
}; };
Ok(InnerDate::<JsObject>::contextualized_day_of_year(&date, context)?.into()) Ok(InnerDate::<JsObject>::contextual_day_of_year(&date, context)?.into())
} }
/// 3.3.10 get `Temporal.PlainDate.prototype.weekOfYear` /// 3.3.10 get `Temporal.PlainDate.prototype.weekOfYear`
@ -377,7 +377,7 @@ impl PlainDate {
.into()); .into());
}; };
Ok(InnerDate::<JsObject>::contextualized_week_of_year(&date, context)?.into()) Ok(InnerDate::<JsObject>::contextual_week_of_year(&date, context)?.into())
} }
/// 3.3.11 get `Temporal.PlainDate.prototype.yearOfWeek` /// 3.3.11 get `Temporal.PlainDate.prototype.yearOfWeek`
@ -392,7 +392,7 @@ impl PlainDate {
.into()); .into());
}; };
Ok(InnerDate::<JsObject>::contextualized_year_of_week(&date, context)?.into()) Ok(InnerDate::<JsObject>::contextual_year_of_week(&date, context)?.into())
} }
/// 3.3.12 get `Temporal.PlainDate.prototype.daysInWeek` /// 3.3.12 get `Temporal.PlainDate.prototype.daysInWeek`
@ -407,7 +407,7 @@ impl PlainDate {
.into()); .into());
}; };
Ok(InnerDate::<JsObject>::contextualized_days_in_week(&date, context)?.into()) Ok(InnerDate::<JsObject>::contextual_days_in_week(&date, context)?.into())
} }
/// 3.3.13 get `Temporal.PlainDate.prototype.daysInMonth` /// 3.3.13 get `Temporal.PlainDate.prototype.daysInMonth`
@ -426,7 +426,7 @@ impl PlainDate {
.into()); .into());
}; };
Ok(InnerDate::<JsObject>::contextualized_days_in_month(&date, context)?.into()) Ok(InnerDate::<JsObject>::contextual_days_in_month(&date, context)?.into())
} }
/// 3.3.14 get `Temporal.PlainDate.prototype.daysInYear` /// 3.3.14 get `Temporal.PlainDate.prototype.daysInYear`
@ -441,7 +441,7 @@ impl PlainDate {
.into()); .into());
}; };
Ok(InnerDate::<JsObject>::contextualized_days_in_year(&date, context)?.into()) Ok(InnerDate::<JsObject>::contextual_days_in_year(&date, context)?.into())
} }
/// 3.3.15 get `Temporal.PlainDate.prototype.monthsInYear` /// 3.3.15 get `Temporal.PlainDate.prototype.monthsInYear`
@ -460,7 +460,7 @@ impl PlainDate {
.into()); .into());
}; };
Ok(InnerDate::<JsObject>::contextualized_months_in_year(&date, context)?.into()) Ok(InnerDate::<JsObject>::contextual_months_in_year(&date, context)?.into())
} }
/// 3.3.16 get `Temporal.PlainDate.prototype.inLeapYear` /// 3.3.16 get `Temporal.PlainDate.prototype.inLeapYear`
@ -475,7 +475,7 @@ impl PlainDate {
.into()); .into());
}; };
Ok(InnerDate::<JsObject>::contextualized_in_leap_year(&date, context)?.into()) Ok(InnerDate::<JsObject>::contextual_in_leap_year(&date, context)?.into())
} }
} }

26
core/engine/src/builtins/temporal/plain_date_time/mod.rs

@ -372,7 +372,7 @@ impl PlainDateTime {
.into()); .into());
}; };
Ok(InnerDateTime::<JsObject>::contextualized_year(&date, context)?.into()) Ok(InnerDateTime::<JsObject>::contextual_year(&date, context)?.into())
} }
/// 5.3.5 get `Temporal.PlainDateTime.prototype.month` /// 5.3.5 get `Temporal.PlainDateTime.prototype.month`
@ -387,7 +387,7 @@ impl PlainDateTime {
.into()); .into());
}; };
Ok(InnerDateTime::<JsObject>::contextualized_month(&date, context)?.into()) Ok(InnerDateTime::<JsObject>::contextual_month(&date, context)?.into())
} }
/// 5.3.6 get Temporal.PlainDateTime.prototype.monthCode /// 5.3.6 get Temporal.PlainDateTime.prototype.monthCode
@ -403,7 +403,7 @@ impl PlainDateTime {
}; };
Ok(JsString::from( Ok(JsString::from(
InnerDateTime::<JsObject>::contextualized_month_code(&date, context)?.as_str(), InnerDateTime::<JsObject>::contextual_month_code(&date, context)?.as_str(),
) )
.into()) .into())
} }
@ -420,7 +420,7 @@ impl PlainDateTime {
.into()); .into());
}; };
Ok(InnerDateTime::<JsObject>::contextualized_day(&date, context)?.into()) Ok(InnerDateTime::<JsObject>::contextual_day(&date, context)?.into())
} }
/// 5.3.8 get `Temporal.PlainDateTime.prototype.hour` /// 5.3.8 get `Temporal.PlainDateTime.prototype.hour`
@ -525,7 +525,7 @@ impl PlainDateTime {
.into()); .into());
}; };
Ok(InnerDateTime::<JsObject>::contextualized_day_of_week(&date, context)?.into()) Ok(InnerDateTime::<JsObject>::contextual_day_of_week(&date, context)?.into())
} }
/// 5.3.15 get `Temporal.PlainDateTime.prototype.dayOfYear` /// 5.3.15 get `Temporal.PlainDateTime.prototype.dayOfYear`
@ -540,7 +540,7 @@ impl PlainDateTime {
.into()); .into());
}; };
Ok(InnerDateTime::<JsObject>::contextualized_day_of_year(&date, context)?.into()) Ok(InnerDateTime::<JsObject>::contextual_day_of_year(&date, context)?.into())
} }
/// 5.3.16 get `Temporal.PlainDateTime.prototype.weekOfYear` /// 5.3.16 get `Temporal.PlainDateTime.prototype.weekOfYear`
@ -555,7 +555,7 @@ impl PlainDateTime {
.into()); .into());
}; };
Ok(InnerDateTime::<JsObject>::contextualized_week_of_year(&date, context)?.into()) Ok(InnerDateTime::<JsObject>::contextual_week_of_year(&date, context)?.into())
} }
/// 5.3.17 get `Temporal.PlainDateTime.prototype.yearOfWeek` /// 5.3.17 get `Temporal.PlainDateTime.prototype.yearOfWeek`
@ -570,7 +570,7 @@ impl PlainDateTime {
.into()); .into());
}; };
Ok(InnerDateTime::<JsObject>::contextualized_year_of_week(&date, context)?.into()) Ok(InnerDateTime::<JsObject>::contextual_year_of_week(&date, context)?.into())
} }
/// 5.3.18 get `Temporal.PlainDateTime.prototype.daysInWeek` /// 5.3.18 get `Temporal.PlainDateTime.prototype.daysInWeek`
@ -585,7 +585,7 @@ impl PlainDateTime {
.into()); .into());
}; };
Ok(InnerDateTime::<JsObject>::contextualized_days_in_week(&date, context)?.into()) Ok(InnerDateTime::<JsObject>::contextual_days_in_week(&date, context)?.into())
} }
/// 5.3.19 get `Temporal.PlainDateTime.prototype.daysInMonth` /// 5.3.19 get `Temporal.PlainDateTime.prototype.daysInMonth`
@ -604,7 +604,7 @@ impl PlainDateTime {
.into()); .into());
}; };
Ok(InnerDateTime::<JsObject>::contextualized_days_in_month(&date, context)?.into()) Ok(InnerDateTime::<JsObject>::contextual_days_in_month(&date, context)?.into())
} }
/// 5.3.20 get `Temporal.PlainDateTime.prototype.daysInYear` /// 5.3.20 get `Temporal.PlainDateTime.prototype.daysInYear`
@ -619,7 +619,7 @@ impl PlainDateTime {
.into()); .into());
}; };
Ok(InnerDateTime::<JsObject>::contextualized_days_in_year(&date, context)?.into()) Ok(InnerDateTime::<JsObject>::contextual_days_in_year(&date, context)?.into())
} }
/// 5.3.21 get `Temporal.PlainDateTime.prototype.monthsInYear` /// 5.3.21 get `Temporal.PlainDateTime.prototype.monthsInYear`
@ -638,7 +638,7 @@ impl PlainDateTime {
.into()); .into());
}; };
Ok(InnerDateTime::<JsObject>::contextualized_months_in_year(&date, context)?.into()) Ok(InnerDateTime::<JsObject>::contextual_months_in_year(&date, context)?.into())
} }
/// 5.3.22 get `Temporal.PlainDateTime.prototype.inLeapYear` /// 5.3.22 get `Temporal.PlainDateTime.prototype.inLeapYear`
@ -653,7 +653,7 @@ impl PlainDateTime {
.into()); .into());
}; };
Ok(InnerDateTime::<JsObject>::contextualized_in_leap_year(&date, context)?.into()) Ok(InnerDateTime::<JsObject>::contextual_in_leap_year(&date, context)?.into())
} }
} }

22
core/engine/src/builtins/temporal/time_zone/custom.rs

@ -14,11 +14,8 @@ pub(crate) struct JsCustomTimeZone {
} }
impl TzProtocol for JsCustomTimeZone { impl TzProtocol for JsCustomTimeZone {
fn get_offset_nanos_for(&self, ctx: &mut dyn std::any::Any) -> TemporalResult<BigInt> { type Context = Context;
let context = ctx fn get_offset_nanos_for(&self, context: &mut Context) -> TemporalResult<BigInt> {
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomTz");
let method = self let method = self
.tz .tz
.get(utf16!("getOffsetNanosFor"), context) .get(utf16!("getOffsetNanosFor"), context)
@ -39,23 +36,12 @@ impl TzProtocol for JsCustomTimeZone {
Ok(bigint.as_inner().clone()) Ok(bigint.as_inner().clone())
} }
fn get_possible_instant_for( fn get_possible_instant_for(&self, _context: &mut Context) -> TemporalResult<Vec<Instant>> {
&self,
ctx: &mut dyn std::any::Any,
) -> TemporalResult<Vec<Instant>> {
let _context = ctx
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomTz");
// TODO: Implement once Instant has been migrated to `boa_temporal`'s Instant. // TODO: Implement once Instant has been migrated to `boa_temporal`'s Instant.
Err(TemporalError::range().with_message("Not yet implemented.")) Err(TemporalError::range().with_message("Not yet implemented."))
} }
fn id(&self, ctx: &mut dyn std::any::Any) -> TemporalResult<String> { fn id(&self, context: &mut Context) -> TemporalResult<String> {
let context = ctx
.downcast_mut::<Context>()
.expect("Context was not provided for a CustomTz");
let ident = self let ident = self
.tz .tz
.__get__( .__get__(

198
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 //! the calendar protocol), but it does aim to provide the necessary tools and API for
//! implementing one. //! implementing one.
use std::{any::Any, str::FromStr}; use std::str::FromStr;
use crate::{ use crate::{
components::{Date, DateTime, Duration, MonthDay, YearMonth}, components::{Date, DateTime, Duration, MonthDay, YearMonth},
@ -88,13 +88,13 @@ impl From<&[String]> for CalendarFieldsType {
#[derive(Debug)] #[derive(Debug)]
pub enum CalendarDateLike<C: CalendarProtocol> { pub enum CalendarDateLike<C: CalendarProtocol> {
/// Represents a user-defined `Date` datelike /// Represents a user-defined `Date` datelike
CustomDate(<<C as CalendarProtocol>::DateLikes as DateTypes<C>>::Date), CustomDate(C::Date),
/// Represents a user-defined `DateTime` datelike /// Represents a user-defined `DateTime` datelike
CustomDateTime(<<C as CalendarProtocol>::DateLikes as DateTypes<C>>::DateTime), CustomDateTime(C::DateTime),
/// Represents a user-defined `YearMonth` datelike /// Represents a user-defined `YearMonth` datelike
CustomYearMonth(<<C as CalendarProtocol>::DateLikes as DateTypes<C>>::YearMonth), CustomYearMonth(C::YearMonth),
/// Represents a user-defined `MonthDay` datelike /// Represents a user-defined `MonthDay` datelike
CustomMonthDay(<<C as CalendarProtocol>::DateLikes as DateTypes<C>>::MonthDay), CustomMonthDay(C::MonthDay),
/// Represents a `DateTime<C>`. /// Represents a `DateTime<C>`.
DateTime(DateTime<C>), DateTime(DateTime<C>),
/// Represents a `Date<C>`. /// Represents a `Date<C>`.
@ -117,45 +117,41 @@ impl<C: CalendarProtocol> CalendarDateLike<C> {
} }
} }
// TODO: DateTypes should implement a trait -> `ToTemporalDate`: `GetCalendarSlot` // ==== CalendarProtocol trait ====
/// A trait for implementing `DateLike` types
pub trait DateTypes<C: CalendarProtocol> { /// 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<C>` /// A Custom `Date` Type for an associated `CalendarProtocol`. Default `Date<C>`
type Date: IsoDateSlots + GetCalendarSlot<C> + Clone + core::fmt::Debug; type Date: IsoDateSlots + GetCalendarSlot<Self> + Clone + core::fmt::Debug;
/// A Custom `DateTime` Type for an associated `CalendarProtocol`. Default `DateTime<C>` /// A Custom `DateTime` Type for an associated `CalendarProtocol`. Default `DateTime<C>`
type DateTime: IsoDateSlots + GetCalendarSlot<C> + Clone + core::fmt::Debug; type DateTime: IsoDateSlots + GetCalendarSlot<Self> + Clone + core::fmt::Debug;
/// A Custom `YearMonth` Type for an associated `CalendarProtocol`. Default `YearMonth<C>` /// A Custom `YearMonth` Type for an associated `CalendarProtocol`. Default `YearMonth<C>`
type YearMonth: IsoDateSlots + GetCalendarSlot<C> + Clone + core::fmt::Debug; type YearMonth: IsoDateSlots + GetCalendarSlot<Self> + Clone + core::fmt::Debug;
/// A Custom `MonthDay` Type for an associated `CalendarProtocol`. Default `MonthDay<C>` /// A Custom `MonthDay` Type for an associated `CalendarProtocol`. Default `MonthDay<C>`
type MonthDay: IsoDateSlots + GetCalendarSlot<C> + Clone + core::fmt::Debug; type MonthDay: IsoDateSlots + GetCalendarSlot<Self> + Clone + core::fmt::Debug;
} /// The context passed to every method of the `CalendarProtocol`.
type Context;
// ==== CalendarProtocol trait ====
/// 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<Self>;
/// Creates a `Temporal.PlainDate` object from provided fields. /// Creates a `Temporal.PlainDate` object from provided fields.
fn date_from_fields( fn date_from_fields(
&self, &self,
fields: &mut TemporalFields, fields: &mut TemporalFields,
overflow: ArithmeticOverflow, overflow: ArithmeticOverflow,
context: &mut dyn Any, context: &mut Self::Context,
) -> TemporalResult<Date<Self>>; ) -> TemporalResult<Date<Self>>;
/// Creates a `Temporal.PlainYearMonth` object from the provided fields. /// Creates a `Temporal.PlainYearMonth` object from the provided fields.
fn year_month_from_fields( fn year_month_from_fields(
&self, &self,
fields: &mut TemporalFields, fields: &mut TemporalFields,
overflow: ArithmeticOverflow, overflow: ArithmeticOverflow,
context: &mut dyn Any, context: &mut Self::Context,
) -> TemporalResult<YearMonth<Self>>; ) -> TemporalResult<YearMonth<Self>>;
/// Creates a `Temporal.PlainMonthDay` object from the provided fields. /// Creates a `Temporal.PlainMonthDay` object from the provided fields.
fn month_day_from_fields( fn month_day_from_fields(
&self, &self,
fields: &mut TemporalFields, fields: &mut TemporalFields,
overflow: ArithmeticOverflow, overflow: ArithmeticOverflow,
context: &mut dyn Any, context: &mut Self::Context,
) -> TemporalResult<MonthDay<Self>>; ) -> TemporalResult<MonthDay<Self>>;
/// Returns a `Temporal.PlainDate` based off an added date. /// Returns a `Temporal.PlainDate` based off an added date.
fn date_add( fn date_add(
@ -163,7 +159,7 @@ pub trait CalendarProtocol: Clone {
date: &Date<Self>, date: &Date<Self>,
duration: &Duration, duration: &Duration,
overflow: ArithmeticOverflow, overflow: ArithmeticOverflow,
context: &mut dyn Any, context: &mut Self::Context,
) -> TemporalResult<Date<Self>>; ) -> TemporalResult<Date<Self>>;
/// Returns a `Temporal.Duration` representing the duration between two dates. /// Returns a `Temporal.Duration` representing the duration between two dates.
fn date_until( fn date_until(
@ -171,106 +167,114 @@ pub trait CalendarProtocol: Clone {
one: &Date<Self>, one: &Date<Self>,
two: &Date<Self>, two: &Date<Self>,
largest_unit: TemporalUnit, largest_unit: TemporalUnit,
context: &mut dyn Any, context: &mut Self::Context,
) -> TemporalResult<Duration>; ) -> TemporalResult<Duration>;
/// Returns the era for a given `temporaldatelike`. /// Returns the era for a given `temporaldatelike`.
fn era( fn era(
&self, &self,
date_like: &CalendarDateLike<Self>, date_like: &CalendarDateLike<Self>,
context: &mut dyn Any, context: &mut Self::Context,
) -> TemporalResult<Option<TinyAsciiStr<16>>>; ) -> TemporalResult<Option<TinyAsciiStr<16>>>;
/// Returns the era year for a given `temporaldatelike` /// Returns the era year for a given `temporaldatelike`
fn era_year( fn era_year(
&self, &self,
date_like: &CalendarDateLike<Self>, date_like: &CalendarDateLike<Self>,
context: &mut dyn Any, context: &mut Self::Context,
) -> TemporalResult<Option<i32>>; ) -> TemporalResult<Option<i32>>;
/// Returns the `year` for a given `temporaldatelike` /// Returns the `year` for a given `temporaldatelike`
fn year( fn year(
&self, &self,
date_like: &CalendarDateLike<Self>, date_like: &CalendarDateLike<Self>,
context: &mut dyn Any, context: &mut Self::Context,
) -> TemporalResult<i32>; ) -> TemporalResult<i32>;
/// Returns the `month` for a given `temporaldatelike` /// Returns the `month` for a given `temporaldatelike`
fn month( fn month(
&self, &self,
date_like: &CalendarDateLike<Self>, date_like: &CalendarDateLike<Self>,
context: &mut dyn Any, context: &mut Self::Context,
) -> TemporalResult<u8>; ) -> TemporalResult<u8>;
// Note: Best practice would probably be to switch to a MonthCode enum after extraction. // Note: Best practice would probably be to switch to a MonthCode enum after extraction.
/// Returns the `monthCode` for a given `temporaldatelike` /// Returns the `monthCode` for a given `temporaldatelike`
fn month_code( fn month_code(
&self, &self,
date_like: &CalendarDateLike<Self>, date_like: &CalendarDateLike<Self>,
context: &mut dyn Any, context: &mut Self::Context,
) -> TemporalResult<TinyAsciiStr<4>>; ) -> TemporalResult<TinyAsciiStr<4>>;
/// Returns the `day` for a given `temporaldatelike` /// Returns the `day` for a given `temporaldatelike`
fn day(&self, date_like: &CalendarDateLike<Self>, context: &mut dyn Any) -> TemporalResult<u8>; fn day(
&self,
date_like: &CalendarDateLike<Self>,
context: &mut Self::Context,
) -> TemporalResult<u8>;
/// Returns a value representing the day of the week for a date. /// Returns a value representing the day of the week for a date.
fn day_of_week( fn day_of_week(
&self, &self,
date_like: &CalendarDateLike<Self>, date_like: &CalendarDateLike<Self>,
context: &mut dyn Any, context: &mut Self::Context,
) -> TemporalResult<u16>; ) -> TemporalResult<u16>;
/// Returns a value representing the day of the year for a given calendar. /// Returns a value representing the day of the year for a given calendar.
fn day_of_year( fn day_of_year(
&self, &self,
date_like: &CalendarDateLike<Self>, date_like: &CalendarDateLike<Self>,
context: &mut dyn Any, context: &mut Self::Context,
) -> TemporalResult<u16>; ) -> TemporalResult<u16>;
/// Returns a value representing the week of the year for a given calendar. /// Returns a value representing the week of the year for a given calendar.
fn week_of_year( fn week_of_year(
&self, &self,
date_like: &CalendarDateLike<Self>, date_like: &CalendarDateLike<Self>,
context: &mut dyn Any, context: &mut Self::Context,
) -> TemporalResult<u16>; ) -> TemporalResult<u16>;
/// Returns the year of a given week. /// Returns the year of a given week.
fn year_of_week( fn year_of_week(
&self, &self,
date_like: &CalendarDateLike<Self>, date_like: &CalendarDateLike<Self>,
context: &mut dyn Any, context: &mut Self::Context,
) -> TemporalResult<i32>; ) -> TemporalResult<i32>;
/// Returns the days in a week for a given calendar. /// Returns the days in a week for a given calendar.
fn days_in_week( fn days_in_week(
&self, &self,
date_like: &CalendarDateLike<Self>, date_like: &CalendarDateLike<Self>,
context: &mut dyn Any, context: &mut Self::Context,
) -> TemporalResult<u16>; ) -> TemporalResult<u16>;
/// Returns the days in a month for a given calendar. /// Returns the days in a month for a given calendar.
fn days_in_month( fn days_in_month(
&self, &self,
date_like: &CalendarDateLike<Self>, date_like: &CalendarDateLike<Self>,
context: &mut dyn Any, context: &mut Self::Context,
) -> TemporalResult<u16>; ) -> TemporalResult<u16>;
/// Returns the days in a year for a given calendar. /// Returns the days in a year for a given calendar.
fn days_in_year( fn days_in_year(
&self, &self,
date_like: &CalendarDateLike<Self>, date_like: &CalendarDateLike<Self>,
context: &mut dyn Any, context: &mut Self::Context,
) -> TemporalResult<u16>; ) -> TemporalResult<u16>;
/// Returns the months in a year for a given calendar. /// Returns the months in a year for a given calendar.
fn months_in_year( fn months_in_year(
&self, &self,
date_like: &CalendarDateLike<Self>, date_like: &CalendarDateLike<Self>,
context: &mut dyn Any, context: &mut Self::Context,
) -> TemporalResult<u16>; ) -> TemporalResult<u16>;
/// Returns whether a value is within a leap year according to the designated calendar. /// Returns whether a value is within a leap year according to the designated calendar.
fn in_leap_year( fn in_leap_year(
&self, &self,
date_like: &CalendarDateLike<Self>, date_like: &CalendarDateLike<Self>,
context: &mut dyn Any, context: &mut Self::Context,
) -> TemporalResult<bool>; ) -> TemporalResult<bool>;
/// Return the fields for a value. /// Return the fields for a value.
fn fields(&self, fields: Vec<String>, context: &mut dyn Any) -> TemporalResult<Vec<String>>; fn fields(
&self,
fields: Vec<String>,
context: &mut Self::Context,
) -> TemporalResult<Vec<String>>;
/// Merge fields based on the calendar and provided values. /// Merge fields based on the calendar and provided values.
fn merge_fields( fn merge_fields(
&self, &self,
fields: &TemporalFields, fields: &TemporalFields,
additional_fields: &TemporalFields, additional_fields: &TemporalFields,
context: &mut dyn Any, context: &mut Self::Context,
) -> TemporalResult<TemporalFields>; ) -> TemporalResult<TemporalFields>;
/// Debug name /// Debug name
fn identifier(&self, context: &mut dyn Any) -> TemporalResult<String>; fn identifier(&self, context: &mut Self::Context) -> TemporalResult<String>;
} }
/// A trait for retrieving an internal calendar slice. /// A trait for retrieving an internal calendar slice.
@ -369,7 +373,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
&self, &self,
fields: &mut TemporalFields, fields: &mut TemporalFields,
overflow: ArithmeticOverflow, overflow: ArithmeticOverflow,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<Date<C>> { ) -> TemporalResult<Date<C>> {
match self { match self {
CalendarSlot::Builtin(AnyCalendar::Iso(_)) => { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => {
@ -412,7 +416,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
&self, &self,
fields: &mut TemporalFields, fields: &mut TemporalFields,
overflow: ArithmeticOverflow, overflow: ArithmeticOverflow,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<MonthDay<C>> { ) -> TemporalResult<MonthDay<C>> {
match self { match self {
CalendarSlot::Builtin(AnyCalendar::Iso(_)) => { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => {
@ -440,7 +444,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
&self, &self,
fields: &mut TemporalFields, fields: &mut TemporalFields,
overflow: ArithmeticOverflow, overflow: ArithmeticOverflow,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<YearMonth<C>> { ) -> TemporalResult<YearMonth<C>> {
match self { match self {
CalendarSlot::Builtin(AnyCalendar::Iso(_)) => { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => {
@ -482,7 +486,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
date: &Date<C>, date: &Date<C>,
duration: &Duration, duration: &Duration,
overflow: ArithmeticOverflow, overflow: ArithmeticOverflow,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<Date<C>> { ) -> TemporalResult<Date<C>> {
match self { match self {
CalendarSlot::Builtin(_) => { CalendarSlot::Builtin(_) => {
@ -500,7 +504,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
one: &Date<C>, one: &Date<C>,
two: &Date<C>, two: &Date<C>,
largest_unit: TemporalUnit, largest_unit: TemporalUnit,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<Duration> { ) -> TemporalResult<Duration> {
match self { match self {
CalendarSlot::Builtin(_) => { CalendarSlot::Builtin(_) => {
@ -516,7 +520,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
pub fn era( pub fn era(
&self, &self,
date_like: &CalendarDateLike<C>, date_like: &CalendarDateLike<C>,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<Option<TinyAsciiStr<16>>> { ) -> TemporalResult<Option<TinyAsciiStr<16>>> {
match self { match self {
CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(None), CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(None),
@ -532,7 +536,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
pub fn era_year( pub fn era_year(
&self, &self,
date_like: &CalendarDateLike<C>, date_like: &CalendarDateLike<C>,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<Option<i32>> { ) -> TemporalResult<Option<i32>> {
match self { match self {
CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(None), CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(None),
@ -548,7 +552,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
pub fn year( pub fn year(
&self, &self,
date_like: &CalendarDateLike<C>, date_like: &CalendarDateLike<C>,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<i32> { ) -> TemporalResult<i32> {
match self { match self {
CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(date_like.as_iso_date().year), CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(date_like.as_iso_date().year),
@ -564,7 +568,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
pub fn month( pub fn month(
&self, &self,
date_like: &CalendarDateLike<C>, date_like: &CalendarDateLike<C>,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<u8> { ) -> TemporalResult<u8> {
match self { match self {
CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(date_like.as_iso_date().month), CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(date_like.as_iso_date().month),
@ -579,7 +583,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
pub fn month_code( pub fn month_code(
&self, &self,
date_like: &CalendarDateLike<C>, date_like: &CalendarDateLike<C>,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<TinyAsciiStr<4>> { ) -> TemporalResult<TinyAsciiStr<4>> {
match self { match self {
CalendarSlot::Builtin(AnyCalendar::Iso(_)) => { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => {
@ -596,7 +600,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
pub fn day( pub fn day(
&self, &self,
date_like: &CalendarDateLike<C>, date_like: &CalendarDateLike<C>,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<u8> { ) -> TemporalResult<u8> {
match self { match self {
CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(date_like.as_iso_date().day), CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(date_like.as_iso_date().day),
@ -611,7 +615,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
pub fn day_of_week( pub fn day_of_week(
&self, &self,
date_like: &CalendarDateLike<C>, date_like: &CalendarDateLike<C>,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
match self { match self {
CalendarSlot::Builtin(AnyCalendar::Iso(_)) => { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => {
@ -628,7 +632,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
pub fn day_of_year( pub fn day_of_year(
&self, &self,
date_like: &CalendarDateLike<C>, date_like: &CalendarDateLike<C>,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
match self { match self {
CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(date_like CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(date_like
@ -647,7 +651,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
pub fn week_of_year( pub fn week_of_year(
&self, &self,
date_like: &CalendarDateLike<C>, date_like: &CalendarDateLike<C>,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
match self { match self {
CalendarSlot::Builtin(AnyCalendar::Iso(_)) => { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => {
@ -672,7 +676,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
pub fn year_of_week( pub fn year_of_week(
&self, &self,
date_like: &CalendarDateLike<C>, date_like: &CalendarDateLike<C>,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<i32> { ) -> TemporalResult<i32> {
match self { match self {
CalendarSlot::Builtin(AnyCalendar::Iso(_)) => { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => {
@ -701,7 +705,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
pub fn days_in_week( pub fn days_in_week(
&self, &self,
date_like: &CalendarDateLike<C>, date_like: &CalendarDateLike<C>,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
match self { match self {
CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(7), CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(7),
@ -716,7 +720,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
pub fn days_in_month( pub fn days_in_month(
&self, &self,
date_like: &CalendarDateLike<C>, date_like: &CalendarDateLike<C>,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
match self { match self {
CalendarSlot::Builtin(AnyCalendar::Iso(_)) => { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => {
@ -734,7 +738,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
pub fn days_in_year( pub fn days_in_year(
&self, &self,
date_like: &CalendarDateLike<C>, date_like: &CalendarDateLike<C>,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
match self { match self {
CalendarSlot::Builtin(AnyCalendar::Iso(_)) => { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => {
@ -751,7 +755,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
pub fn months_in_year( pub fn months_in_year(
&self, &self,
date_like: &CalendarDateLike<C>, date_like: &CalendarDateLike<C>,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
match self { match self {
CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(12), CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(12),
@ -766,7 +770,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
pub fn in_leap_year( pub fn in_leap_year(
&self, &self,
date_like: &CalendarDateLike<C>, date_like: &CalendarDateLike<C>,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<bool> { ) -> TemporalResult<bool> {
match self { match self {
CalendarSlot::Builtin(AnyCalendar::Iso(_)) => { CalendarSlot::Builtin(AnyCalendar::Iso(_)) => {
@ -783,7 +787,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
pub fn fields( pub fn fields(
&self, &self,
fields: Vec<String>, fields: Vec<String>,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<Vec<String>> { ) -> TemporalResult<Vec<String>> {
match self { match self {
CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(fields), CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(fields),
@ -799,7 +803,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
&self, &self,
fields: &TemporalFields, fields: &TemporalFields,
additional_fields: &TemporalFields, additional_fields: &TemporalFields,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<TemporalFields> { ) -> TemporalResult<TemporalFields> {
match self { match self {
CalendarSlot::Builtin(_) => fields.merge_fields(additional_fields, self), CalendarSlot::Builtin(_) => fields.merge_fields(additional_fields, self),
@ -810,7 +814,7 @@ impl<C: CalendarProtocol> CalendarSlot<C> {
} }
/// Returns the identifier of this calendar slot. /// Returns the identifier of this calendar slot.
pub fn identifier(&self, context: &mut dyn Any) -> TemporalResult<String> { pub fn identifier(&self, context: &mut C::Context) -> TemporalResult<String> {
match self { match self {
CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(String::from("iso8601")), CalendarSlot::Builtin(AnyCalendar::Iso(_)) => Ok(String::from("iso8601")),
CalendarSlot::Builtin(builtin) => Ok(String::from(builtin.debug_name())), 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 `()`. /// An empty `CalendarProtocol` implementation on `()`.
/// ///
/// # Panics /// # Panics
/// ///
/// Attempting to use this empty calendar implementation as a valid calendar is an error and will cause a panic. /// Attempting to use this empty calendar implementation as a valid calendar is an error and will cause a panic.
impl CalendarProtocol for () { impl CalendarProtocol for () {
type DateLikes = (); type Date = Date<()>;
type DateTime = DateTime<()>;
type YearMonth = YearMonth<()>;
type MonthDay = MonthDay<()>;
type Context = ();
fn date_from_fields( fn date_from_fields(
&self, &self,
_: &mut TemporalFields, _: &mut TemporalFields,
_: ArithmeticOverflow, _: ArithmeticOverflow,
_: &mut dyn Any, (): &mut (),
) -> TemporalResult<Date<Self>> { ) -> TemporalResult<Date<Self>> {
unreachable!(); unreachable!();
} }
@ -884,7 +890,7 @@ impl CalendarProtocol for () {
&self, &self,
_: &mut TemporalFields, _: &mut TemporalFields,
_: ArithmeticOverflow, _: ArithmeticOverflow,
_: &mut dyn Any, (): &mut (),
) -> TemporalResult<MonthDay<()>> { ) -> TemporalResult<MonthDay<()>> {
unreachable!(); unreachable!();
} }
@ -893,7 +899,7 @@ impl CalendarProtocol for () {
&self, &self,
_: &mut TemporalFields, _: &mut TemporalFields,
_: ArithmeticOverflow, _: ArithmeticOverflow,
_: &mut dyn Any, (): &mut (),
) -> TemporalResult<YearMonth<Self>> { ) -> TemporalResult<YearMonth<Self>> {
unreachable!() unreachable!()
} }
@ -903,7 +909,7 @@ impl CalendarProtocol for () {
_: &Date<Self>, _: &Date<Self>,
_: &Duration, _: &Duration,
_: ArithmeticOverflow, _: ArithmeticOverflow,
_: &mut dyn Any, (): &mut (),
) -> TemporalResult<Date<Self>> { ) -> TemporalResult<Date<Self>> {
unreachable!(); unreachable!();
} }
@ -913,7 +919,7 @@ impl CalendarProtocol for () {
_: &Date<()>, _: &Date<()>,
_: &Date<()>, _: &Date<()>,
_: TemporalUnit, _: TemporalUnit,
_: &mut dyn Any, (): &mut (),
) -> TemporalResult<Duration> { ) -> TemporalResult<Duration> {
unreachable!(); unreachable!();
} }
@ -921,72 +927,72 @@ impl CalendarProtocol for () {
fn era( fn era(
&self, &self,
_: &CalendarDateLike<Self>, _: &CalendarDateLike<Self>,
_: &mut dyn Any, (): &mut (),
) -> TemporalResult<Option<TinyAsciiStr<16>>> { ) -> TemporalResult<Option<TinyAsciiStr<16>>> {
unreachable!(); unreachable!();
} }
fn era_year(&self, _: &CalendarDateLike<Self>, _: &mut dyn Any) -> TemporalResult<Option<i32>> { fn era_year(&self, _: &CalendarDateLike<Self>, (): &mut ()) -> TemporalResult<Option<i32>> {
unreachable!(); unreachable!();
} }
fn year(&self, _: &CalendarDateLike<Self>, _: &mut dyn Any) -> TemporalResult<i32> { fn year(&self, _: &CalendarDateLike<Self>, (): &mut ()) -> TemporalResult<i32> {
unreachable!(); unreachable!();
} }
fn month(&self, _: &CalendarDateLike<Self>, _: &mut dyn Any) -> TemporalResult<u8> { fn month(&self, _: &CalendarDateLike<Self>, (): &mut ()) -> TemporalResult<u8> {
unreachable!(); unreachable!();
} }
fn month_code( fn month_code(
&self, &self,
_: &CalendarDateLike<Self>, _: &CalendarDateLike<Self>,
_: &mut dyn Any, (): &mut (),
) -> TemporalResult<TinyAsciiStr<4>> { ) -> TemporalResult<TinyAsciiStr<4>> {
unreachable!(); unreachable!();
} }
fn day(&self, _: &CalendarDateLike<Self>, _: &mut dyn Any) -> TemporalResult<u8> { fn day(&self, _: &CalendarDateLike<Self>, (): &mut ()) -> TemporalResult<u8> {
unreachable!(); unreachable!();
} }
fn day_of_week(&self, _: &CalendarDateLike<Self>, _: &mut dyn Any) -> TemporalResult<u16> { fn day_of_week(&self, _: &CalendarDateLike<Self>, (): &mut ()) -> TemporalResult<u16> {
unreachable!(); unreachable!();
} }
fn day_of_year(&self, _: &CalendarDateLike<Self>, _: &mut dyn Any) -> TemporalResult<u16> { fn day_of_year(&self, _: &CalendarDateLike<Self>, (): &mut ()) -> TemporalResult<u16> {
unreachable!(); unreachable!();
} }
fn week_of_year(&self, _: &CalendarDateLike<Self>, _: &mut dyn Any) -> TemporalResult<u16> { fn week_of_year(&self, _: &CalendarDateLike<Self>, (): &mut ()) -> TemporalResult<u16> {
unreachable!(); unreachable!();
} }
fn year_of_week(&self, _: &CalendarDateLike<Self>, _: &mut dyn Any) -> TemporalResult<i32> { fn year_of_week(&self, _: &CalendarDateLike<Self>, (): &mut ()) -> TemporalResult<i32> {
unreachable!(); unreachable!();
} }
fn days_in_week(&self, _: &CalendarDateLike<Self>, _: &mut dyn Any) -> TemporalResult<u16> { fn days_in_week(&self, _: &CalendarDateLike<Self>, (): &mut ()) -> TemporalResult<u16> {
unreachable!(); unreachable!();
} }
fn days_in_month(&self, _: &CalendarDateLike<Self>, _: &mut dyn Any) -> TemporalResult<u16> { fn days_in_month(&self, _: &CalendarDateLike<Self>, (): &mut ()) -> TemporalResult<u16> {
unreachable!(); unreachable!();
} }
fn days_in_year(&self, _: &CalendarDateLike<Self>, _: &mut dyn Any) -> TemporalResult<u16> { fn days_in_year(&self, _: &CalendarDateLike<Self>, (): &mut ()) -> TemporalResult<u16> {
unreachable!(); unreachable!();
} }
fn months_in_year(&self, _: &CalendarDateLike<Self>, _: &mut dyn Any) -> TemporalResult<u16> { fn months_in_year(&self, _: &CalendarDateLike<Self>, (): &mut ()) -> TemporalResult<u16> {
unreachable!(); unreachable!();
} }
fn in_leap_year(&self, _: &CalendarDateLike<Self>, _: &mut dyn Any) -> TemporalResult<bool> { fn in_leap_year(&self, _: &CalendarDateLike<Self>, (): &mut ()) -> TemporalResult<bool> {
unreachable!(); unreachable!();
} }
fn fields(&self, _: Vec<String>, _: &mut dyn Any) -> TemporalResult<Vec<String>> { fn fields(&self, _: Vec<String>, (): &mut ()) -> TemporalResult<Vec<String>> {
unreachable!(); unreachable!();
} }
@ -994,12 +1000,12 @@ impl CalendarProtocol for () {
&self, &self,
_: &TemporalFields, _: &TemporalFields,
_: &TemporalFields, _: &TemporalFields,
_: &mut dyn Any, (): &mut (),
) -> TemporalResult<TemporalFields> { ) -> TemporalResult<TemporalFields> {
unreachable!(); unreachable!();
} }
fn identifier(&self, _: &mut dyn Any) -> TemporalResult<String> { fn identifier(&self, (): &mut ()) -> TemporalResult<String> {
unreachable!(); unreachable!();
} }
} }

107
core/temporal/src/components/date.rs

@ -13,10 +13,10 @@ use crate::{
parser::parse_date_time, parser::parse_date_time,
TemporalError, TemporalResult, TemporalError, TemporalResult,
}; };
use std::{any::Any, str::FromStr}; use std::str::FromStr;
use super::{ use super::{
calendar::{CalendarDateLike, DateTypes, GetCalendarSlot}, calendar::{CalendarDateLike, GetCalendarSlot},
duration::TimeDuration, duration::TimeDuration,
}; };
@ -42,7 +42,7 @@ impl<C: CalendarProtocol> Date<C> {
pub(crate) fn move_relative_date( pub(crate) fn move_relative_date(
&self, &self,
duration: &Duration, duration: &Duration,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<(Self, f64)> { ) -> TemporalResult<(Self, f64)> {
let new_date = let new_date =
self.contextual_add_date(duration, ArithmeticOverflow::Constrain, context)?; self.contextual_add_date(duration, ArithmeticOverflow::Constrain, context)?;
@ -215,117 +215,102 @@ impl Date<()> {
// reference count increment. Need to test. // reference count increment. Need to test.
impl<C: CalendarProtocol> Date<C> { impl<C: CalendarProtocol> Date<C> {
/// Returns the calendar year value with provided context. /// Returns the calendar year value with provided context.
pub fn contextualized_year( pub fn contextual_year(this: &C::Date, context: &mut C::Context) -> TemporalResult<i32> {
this: &<C::DateLikes as DateTypes<C>>::Date,
context: &mut dyn Any,
) -> TemporalResult<i32> {
this.get_calendar() this.get_calendar()
.year(&CalendarDateLike::CustomDate(this.clone()), context) .year(&CalendarDateLike::CustomDate(this.clone()), context)
} }
/// Returns the calendar month value with provided context. /// Returns the calendar month value with provided context.
pub fn contextualized_month( pub fn contextual_month(this: &C::Date, context: &mut C::Context) -> TemporalResult<u8> {
this: &<C::DateLikes as DateTypes<C>>::Date,
context: &mut dyn Any,
) -> TemporalResult<u8> {
this.get_calendar() this.get_calendar()
.month(&CalendarDateLike::CustomDate(this.clone()), context) .month(&CalendarDateLike::CustomDate(this.clone()), context)
} }
/// Returns the calendar month code value with provided context. /// Returns the calendar month code value with provided context.
pub fn contextualized_month_code( pub fn contextual_month_code(
this: &<C::DateLikes as DateTypes<C>>::Date, this: &C::Date,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<TinyAsciiStr<4>> { ) -> TemporalResult<TinyAsciiStr<4>> {
this.get_calendar() this.get_calendar()
.month_code(&CalendarDateLike::CustomDate(this.clone()), context) .month_code(&CalendarDateLike::CustomDate(this.clone()), context)
} }
/// Returns the calendar day value with provided context. /// Returns the calendar day value with provided context.
pub fn contextualized_day( pub fn contextual_day(this: &C::Date, context: &mut C::Context) -> TemporalResult<u8> {
this: &<C::DateLikes as DateTypes<C>>::Date,
context: &mut dyn Any,
) -> TemporalResult<u8> {
this.get_calendar() this.get_calendar()
.day(&CalendarDateLike::CustomDate(this.clone()), context) .day(&CalendarDateLike::CustomDate(this.clone()), context)
} }
/// Returns the calendar day of week value with provided context. /// Returns the calendar day of week value with provided context.
pub fn contextualized_day_of_week( pub fn contextual_day_of_week(this: &C::Date, context: &mut C::Context) -> TemporalResult<u16> {
this: &<C::DateLikes as DateTypes<C>>::Date,
context: &mut dyn Any,
) -> TemporalResult<u16> {
this.get_calendar() this.get_calendar()
.day_of_week(&CalendarDateLike::CustomDate(this.clone()), context) .day_of_week(&CalendarDateLike::CustomDate(this.clone()), context)
} }
/// Returns the calendar day of year value with provided context. /// Returns the calendar day of year value with provided context.
pub fn contextualized_day_of_year( pub fn contextual_day_of_year(this: &C::Date, context: &mut C::Context) -> TemporalResult<u16> {
this: &<C::DateLikes as DateTypes<C>>::Date,
context: &mut dyn Any,
) -> TemporalResult<u16> {
this.get_calendar() this.get_calendar()
.day_of_year(&CalendarDateLike::CustomDate(this.clone()), context) .day_of_year(&CalendarDateLike::CustomDate(this.clone()), context)
} }
/// Returns the calendar week of year value with provided context. /// Returns the calendar week of year value with provided context.
pub fn contextualized_week_of_year( pub fn contextual_week_of_year(
this: &<C::DateLikes as DateTypes<C>>::Date, this: &C::Date,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
this.get_calendar() this.get_calendar()
.week_of_year(&CalendarDateLike::CustomDate(this.clone()), context) .week_of_year(&CalendarDateLike::CustomDate(this.clone()), context)
} }
/// Returns the calendar year of week value with provided context. /// Returns the calendar year of week value with provided context.
pub fn contextualized_year_of_week( pub fn contextual_year_of_week(
this: &<C::DateLikes as DateTypes<C>>::Date, this: &C::Date,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<i32> { ) -> TemporalResult<i32> {
this.get_calendar() this.get_calendar()
.year_of_week(&CalendarDateLike::CustomDate(this.clone()), context) .year_of_week(&CalendarDateLike::CustomDate(this.clone()), context)
} }
/// Returns the calendar days in week value with provided context. /// Returns the calendar days in week value with provided context.
pub fn contextualized_days_in_week( pub fn contextual_days_in_week(
this: &<C::DateLikes as DateTypes<C>>::Date, this: &C::Date,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
this.get_calendar() this.get_calendar()
.days_in_week(&CalendarDateLike::CustomDate(this.clone()), context) .days_in_week(&CalendarDateLike::CustomDate(this.clone()), context)
} }
/// Returns the calendar days in month value with provided context. /// Returns the calendar days in month value with provided context.
pub fn contextualized_days_in_month( pub fn contextual_days_in_month(
this: &<C::DateLikes as DateTypes<C>>::Date, this: &C::Date,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
this.get_calendar() this.get_calendar()
.days_in_month(&CalendarDateLike::CustomDate(this.clone()), context) .days_in_month(&CalendarDateLike::CustomDate(this.clone()), context)
} }
/// Returns the calendar days in year value with provided context. /// Returns the calendar days in year value with provided context.
pub fn contextualized_days_in_year( pub fn contextual_days_in_year(
this: &<C::DateLikes as DateTypes<C>>::Date, this: &C::Date,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
this.get_calendar() this.get_calendar()
.days_in_year(&CalendarDateLike::CustomDate(this.clone()), context) .days_in_year(&CalendarDateLike::CustomDate(this.clone()), context)
} }
/// Returns the calendar months in year value with provided context. /// Returns the calendar months in year value with provided context.
pub fn contextualized_months_in_year( pub fn contextual_months_in_year(
this: &<C::DateLikes as DateTypes<C>>::Date, this: &C::Date,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
this.get_calendar() this.get_calendar()
.months_in_year(&CalendarDateLike::CustomDate(this.clone()), context) .months_in_year(&CalendarDateLike::CustomDate(this.clone()), context)
} }
/// Returns whether the date is in a leap year for the given calendar with provided context. /// Returns whether the date is in a leap year for the given calendar with provided context.
pub fn contextualized_in_leap_year( pub fn contextual_in_leap_year(
this: &<C::DateLikes as DateTypes<C>>::Date, this: &C::Date,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<bool> { ) -> TemporalResult<bool> {
this.get_calendar() this.get_calendar()
.in_leap_year(&CalendarDateLike::CustomDate(this.clone()), context) .in_leap_year(&CalendarDateLike::CustomDate(this.clone()), context)
@ -356,7 +341,7 @@ impl<C: CalendarProtocol> Date<C> {
&self, &self,
duration: &Duration, duration: &Duration,
overflow: ArithmeticOverflow, overflow: ArithmeticOverflow,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<Self> { ) -> TemporalResult<Self> {
// 1. If options is not present, set options to undefined. // 1. If options is not present, set options to undefined.
// 2. If duration.[[Years]] ≠ 0, or duration.[[Months]] ≠ 0, or duration.[[Weeks]] ≠ 0, then // 2. If duration.[[Years]] ≠ 0, or duration.[[Months]] ≠ 0, or duration.[[Weeks]] ≠ 0, then
@ -391,18 +376,6 @@ impl<C: CalendarProtocol> Date<C> {
Ok(Self::new_unchecked(result, self.calendar().clone())) 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> {
self.contextual_add_date(duration, overflow, &mut ())
}
/// Returns a duration representing the difference between the dates one and two with a provided context. /// 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 )` /// Temporal Equivalent: 3.5.6 `DifferenceDate ( calendar, one, two, options )`
@ -411,7 +384,7 @@ impl<C: CalendarProtocol> Date<C> {
&self, &self,
other: &Self, other: &Self,
largest_unit: TemporalUnit, largest_unit: TemporalUnit,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<Duration> { ) -> TemporalResult<Duration> {
if self.iso.year == other.iso.year if self.iso.year == other.iso.year
&& self.iso.month == other.iso.month && self.iso.month == other.iso.month
@ -433,18 +406,6 @@ impl<C: CalendarProtocol> Date<C> {
self.calendar() self.calendar()
.date_until(self, other, largest_unit, context) .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<Duration> {
self.contextual_difference_date(other, largest_unit, &mut ())
}
} }
// ==== Trait impls ==== // ==== Trait impls ====

79
core/temporal/src/components/datetime.rs

@ -11,10 +11,10 @@ use crate::{
TemporalError, TemporalResult, TemporalError, TemporalResult,
}; };
use std::{any::Any, str::FromStr}; use std::str::FromStr;
use tinystr::TinyAsciiStr; use tinystr::TinyAsciiStr;
use super::calendar::{CalendarDateLike, DateTypes, GetCalendarSlot}; use super::calendar::{CalendarDateLike, GetCalendarSlot};
/// The native Rust implementation of `Temporal.PlainDateTime` /// The native Rust implementation of `Temporal.PlainDateTime`
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
@ -248,117 +248,108 @@ impl DateTime<()> {
impl<C: CalendarProtocol> DateTime<C> { impl<C: CalendarProtocol> DateTime<C> {
/// Returns the calendar year value with provided context. /// Returns the calendar year value with provided context.
pub fn contextualized_year( pub fn contextual_year(this: &C::DateTime, context: &mut C::Context) -> TemporalResult<i32> {
this: &<C::DateLikes as DateTypes<C>>::DateTime,
context: &mut dyn Any,
) -> TemporalResult<i32> {
this.get_calendar() this.get_calendar()
.year(&CalendarDateLike::CustomDateTime(this.clone()), context) .year(&CalendarDateLike::CustomDateTime(this.clone()), context)
} }
/// Returns the calendar month value with provided context. /// Returns the calendar month value with provided context.
pub fn contextualized_month( pub fn contextual_month(this: &C::DateTime, context: &mut C::Context) -> TemporalResult<u8> {
this: &<C::DateLikes as DateTypes<C>>::DateTime,
context: &mut dyn Any,
) -> TemporalResult<u8> {
this.get_calendar() this.get_calendar()
.month(&CalendarDateLike::CustomDateTime(this.clone()), context) .month(&CalendarDateLike::CustomDateTime(this.clone()), context)
} }
/// Returns the calendar month code value with provided context. /// Returns the calendar month code value with provided context.
pub fn contextualized_month_code( pub fn contextual_month_code(
this: &<C::DateLikes as DateTypes<C>>::DateTime, this: &C::DateTime,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<TinyAsciiStr<4>> { ) -> TemporalResult<TinyAsciiStr<4>> {
this.get_calendar() this.get_calendar()
.month_code(&CalendarDateLike::CustomDateTime(this.clone()), context) .month_code(&CalendarDateLike::CustomDateTime(this.clone()), context)
} }
/// Returns the calendar day value with provided context. /// Returns the calendar day value with provided context.
pub fn contextualized_day( pub fn contextual_day(this: &C::DateTime, context: &mut C::Context) -> TemporalResult<u8> {
this: &<C::DateLikes as DateTypes<C>>::DateTime,
context: &mut dyn Any,
) -> TemporalResult<u8> {
this.get_calendar() this.get_calendar()
.day(&CalendarDateLike::CustomDateTime(this.clone()), context) .day(&CalendarDateLike::CustomDateTime(this.clone()), context)
} }
/// Returns the calendar day of week value with provided context. /// Returns the calendar day of week value with provided context.
pub fn contextualized_day_of_week( pub fn contextual_day_of_week(
this: &<C::DateLikes as DateTypes<C>>::DateTime, this: &C::DateTime,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
this.get_calendar() this.get_calendar()
.day_of_week(&CalendarDateLike::CustomDateTime(this.clone()), context) .day_of_week(&CalendarDateLike::CustomDateTime(this.clone()), context)
} }
/// Returns the calendar day of year value with provided context. /// Returns the calendar day of year value with provided context.
pub fn contextualized_day_of_year( pub fn contextual_day_of_year(
this: &<C::DateLikes as DateTypes<C>>::DateTime, this: &C::DateTime,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
this.get_calendar() this.get_calendar()
.day_of_year(&CalendarDateLike::CustomDateTime(this.clone()), context) .day_of_year(&CalendarDateLike::CustomDateTime(this.clone()), context)
} }
/// Returns the calendar week of year value with provided context. /// Returns the calendar week of year value with provided context.
pub fn contextualized_week_of_year( pub fn contextual_week_of_year(
this: &<C::DateLikes as DateTypes<C>>::DateTime, this: &C::DateTime,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
this.get_calendar() this.get_calendar()
.week_of_year(&CalendarDateLike::CustomDateTime(this.clone()), context) .week_of_year(&CalendarDateLike::CustomDateTime(this.clone()), context)
} }
/// Returns the calendar year of week value with provided context. /// Returns the calendar year of week value with provided context.
pub fn contextualized_year_of_week( pub fn contextual_year_of_week(
this: &<C::DateLikes as DateTypes<C>>::DateTime, this: &C::DateTime,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<i32> { ) -> TemporalResult<i32> {
this.get_calendar() this.get_calendar()
.year_of_week(&CalendarDateLike::CustomDateTime(this.clone()), context) .year_of_week(&CalendarDateLike::CustomDateTime(this.clone()), context)
} }
/// Returns the calendar days in week value with provided context. /// Returns the calendar days in week value with provided context.
pub fn contextualized_days_in_week( pub fn contextual_days_in_week(
this: &<C::DateLikes as DateTypes<C>>::DateTime, this: &C::DateTime,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
this.get_calendar() this.get_calendar()
.days_in_week(&CalendarDateLike::CustomDateTime(this.clone()), context) .days_in_week(&CalendarDateLike::CustomDateTime(this.clone()), context)
} }
/// Returns the calendar days in month value with provided context. /// Returns the calendar days in month value with provided context.
pub fn contextualized_days_in_month( pub fn contextual_days_in_month(
this: &<C::DateLikes as DateTypes<C>>::DateTime, this: &C::DateTime,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
this.get_calendar() this.get_calendar()
.days_in_month(&CalendarDateLike::CustomDateTime(this.clone()), context) .days_in_month(&CalendarDateLike::CustomDateTime(this.clone()), context)
} }
/// Returns the calendar days in year value with provided context. /// Returns the calendar days in year value with provided context.
pub fn contextualized_days_in_year( pub fn contextual_days_in_year(
this: &<C::DateLikes as DateTypes<C>>::DateTime, this: &C::DateTime,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
this.get_calendar() this.get_calendar()
.days_in_year(&CalendarDateLike::CustomDateTime(this.clone()), context) .days_in_year(&CalendarDateLike::CustomDateTime(this.clone()), context)
} }
/// Returns the calendar months in year value with provided context. /// Returns the calendar months in year value with provided context.
pub fn contextualized_months_in_year( pub fn contextual_months_in_year(
this: &<C::DateLikes as DateTypes<C>>::DateTime, this: &C::DateTime,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<u16> { ) -> TemporalResult<u16> {
this.get_calendar() this.get_calendar()
.months_in_year(&CalendarDateLike::CustomDateTime(this.clone()), context) .months_in_year(&CalendarDateLike::CustomDateTime(this.clone()), context)
} }
/// Returns whether the date is in a leap year for the given calendar with provided context. /// Returns whether the date is in a leap year for the given calendar with provided context.
pub fn contextualized_in_leap_year( pub fn contextual_in_leap_year(
this: &<C::DateLikes as DateTypes<C>>::DateTime, this: &C::DateTime,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<bool> { ) -> TemporalResult<bool> {
this.get_calendar() this.get_calendar()
.in_leap_year(&CalendarDateLike::CustomDateTime(this.clone()), context) .in_leap_year(&CalendarDateLike::CustomDateTime(this.clone()), context)

8
core/temporal/src/components/duration.rs

@ -6,7 +6,7 @@ use crate::{
parser::{duration::parse_duration, Cursor}, parser::{duration::parse_duration, Cursor},
TemporalError, TemporalResult, TemporalError, TemporalResult,
}; };
use std::{any::Any, str::FromStr}; use std::str::FromStr;
use super::{calendar::CalendarProtocol, tz::TzProtocol}; use super::{calendar::CalendarProtocol, tz::TzProtocol};
@ -370,7 +370,7 @@ impl Duration {
&self, &self,
largest_unit: TemporalUnit, largest_unit: TemporalUnit,
plain_relative_to: Option<&Date<C>>, plain_relative_to: Option<&Date<C>>,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<DateDuration> { ) -> TemporalResult<DateDuration> {
// 1. Let allZero be false. // 1. Let allZero be false.
// 2. If years = 0, and months = 0, and weeks = 0, and days = 0, set allZero to true. // 2. If years = 0, and months = 0, and weeks = 0, and days = 0, set allZero to true.
@ -576,7 +576,7 @@ impl Duration {
&self, &self,
largest_unit: TemporalUnit, largest_unit: TemporalUnit,
plain_relative_to: Option<&Date<C>>, plain_relative_to: Option<&Date<C>>,
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<DateDuration> { ) -> TemporalResult<DateDuration> {
let mut result = self.date; let mut result = self.date;
@ -816,7 +816,7 @@ impl Duration {
Option<&ZonedDateTime<C, Z>>, Option<&ZonedDateTime<C, Z>>,
Option<&DateTime<C>>, Option<&DateTime<C>>,
), ),
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<(Self, f64)> { ) -> TemporalResult<(Self, f64)> {
match unit { match unit {
TemporalUnit::Year | TemporalUnit::Month | TemporalUnit::Week | TemporalUnit::Day => { TemporalUnit::Year | TemporalUnit::Month | TemporalUnit::Week | TemporalUnit::Day => {

4
core/temporal/src/components/duration/date.rs

@ -9,8 +9,6 @@ use crate::{
utils, TemporalError, TemporalResult, NS_PER_DAY, utils, TemporalError, TemporalResult, NS_PER_DAY,
}; };
use std::any::Any;
/// `DateDuration` represents the [date duration record][spec] of the `Duration.` /// `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. /// 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<C, Z>>, Option<&ZonedDateTime<C, Z>>,
Option<&DateTime<C>>, Option<&DateTime<C>>,
), ),
context: &mut dyn Any, context: &mut C::Context,
) -> TemporalResult<(Self, f64)> { ) -> TemporalResult<(Self, f64)> {
// 1. If plainRelativeTo is not present, set plainRelativeTo to undefined. // 1. If plainRelativeTo is not present, set plainRelativeTo to undefined.
let plain_relative_to = relative_targets.0; let plain_relative_to = relative_targets.0;

29
core/temporal/src/components/tz.rs

@ -1,7 +1,5 @@
//! This module implements the Temporal `TimeZone` and components. //! This module implements the Temporal `TimeZone` and components.
use std::any::Any;
use num_bigint::BigInt; use num_bigint::BigInt;
use num_traits::ToPrimitive; 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. /// The Time Zone Protocol that must be implemented for time zones.
pub trait TzProtocol: Clone { pub trait TzProtocol: Clone {
/// The context passed to every method of the `TzProtocol`.
type Context;
/// Get the Offset nanoseconds for this `TimeZone` /// Get the Offset nanoseconds for this `TimeZone`
fn get_offset_nanos_for(&self, context: &mut dyn Any) -> TemporalResult<BigInt>; fn get_offset_nanos_for(&self, context: &mut Self::Context) -> TemporalResult<BigInt>;
/// Get the possible Instant for this `TimeZone` /// Get the possible Instant for this `TimeZone`
fn get_possible_instant_for(&self, context: &mut dyn Any) -> TemporalResult<Vec<Instant>>; // TODO: Implement Instant fn get_possible_instant_for(&self, context: &mut Self::Context)
-> TemporalResult<Vec<Instant>>; // TODO: Implement Instant
/// Get the `TimeZone`'s identifier. /// Get the `TimeZone`'s identifier.
fn id(&self, context: &mut dyn Any) -> TemporalResult<String>; fn id(&self, context: &mut Self::Context) -> TemporalResult<String>;
} }
/// A Temporal `TimeZone`. /// A Temporal `TimeZone`.
@ -57,7 +58,7 @@ impl<Z: TzProtocol> TimeZoneSlot<Z> {
&self, &self,
instant: &Instant, instant: &Instant,
calendar: &CalendarSlot<C>, calendar: &CalendarSlot<C>,
context: &mut dyn Any, context: &mut Z::Context,
) -> TemporalResult<DateTime<C>> { ) -> TemporalResult<DateTime<C>> {
let nanos = self.get_offset_nanos_for(context)?; let nanos = self.get_offset_nanos_for(context)?;
DateTime::from_instant(instant, nanos.to_f64().unwrap_or(0.0), calendar.clone()) DateTime::from_instant(instant, nanos.to_f64().unwrap_or(0.0), calendar.clone())
@ -66,7 +67,7 @@ impl<Z: TzProtocol> TimeZoneSlot<Z> {
impl<Z: TzProtocol> TimeZoneSlot<Z> { impl<Z: TzProtocol> TimeZoneSlot<Z> {
/// Get the offset for this current `TimeZoneSlot`. /// Get the offset for this current `TimeZoneSlot`.
pub fn get_offset_nanos_for(&self, context: &mut dyn Any) -> TemporalResult<BigInt> { pub fn get_offset_nanos_for(&self, context: &mut Z::Context) -> TemporalResult<BigInt> {
// 1. Let timeZone be the this value. // 1. Let timeZone be the this value.
// 2. Perform ? RequireInternalSlot(timeZone, [[InitializedTemporalTimeZone]]). // 2. Perform ? RequireInternalSlot(timeZone, [[InitializedTemporalTimeZone]]).
// 3. Set instant to ? ToTemporalInstant(instant). // 3. Set instant to ? ToTemporalInstant(instant).
@ -85,12 +86,15 @@ impl<Z: TzProtocol> TimeZoneSlot<Z> {
} }
/// Get the possible `Instant`s for this `TimeZoneSlot`. /// Get the possible `Instant`s for this `TimeZoneSlot`.
pub fn get_possible_instant_for(&self, _context: &mut dyn Any) -> TemporalResult<Vec<Instant>> { pub fn get_possible_instant_for(
&self,
_context: &mut Z::Context,
) -> TemporalResult<Vec<Instant>> {
Err(TemporalError::general("Not yet implemented.")) Err(TemporalError::general("Not yet implemented."))
} }
/// Returns the current `TimeZoneSlot`'s identifier. /// Returns the current `TimeZoneSlot`'s identifier.
pub fn id(&self, context: &mut dyn Any) -> TemporalResult<String> { pub fn id(&self, context: &mut Z::Context) -> TemporalResult<String> {
match self { match self {
Self::Tz(_) => Err(TemporalError::range().with_message("Not yet implemented.")), // TODO: Implement Display for Time Zone. Self::Tz(_) => Err(TemporalError::range().with_message("Not yet implemented.")), // TODO: Implement Display for Time Zone.
Self::Protocol(tz) => tz.id(context), Self::Protocol(tz) => tz.id(context),
@ -99,15 +103,16 @@ impl<Z: TzProtocol> TimeZoneSlot<Z> {
} }
impl TzProtocol for () { impl TzProtocol for () {
fn get_offset_nanos_for(&self, _: &mut dyn Any) -> TemporalResult<BigInt> { type Context = ();
fn get_offset_nanos_for(&self, (): &mut ()) -> TemporalResult<BigInt> {
unreachable!() unreachable!()
} }
fn get_possible_instant_for(&self, _: &mut dyn Any) -> TemporalResult<Vec<Instant>> { fn get_possible_instant_for(&self, (): &mut ()) -> TemporalResult<Vec<Instant>> {
unreachable!() unreachable!()
} }
fn id(&self, _: &mut dyn Any) -> TemporalResult<String> { fn id(&self, (): &mut ()) -> TemporalResult<String> {
Ok("() TimeZone".to_owned()) Ok("() TimeZone".to_owned())
} }
} }

104
core/temporal/src/components/zoneddatetime.rs

@ -12,8 +12,6 @@ use crate::{
TemporalResult, TemporalResult,
}; };
use core::any::Any;
use super::tz::TzProtocol; use super::tz::TzProtocol;
/// The native Rust implementation of `Temporal.ZonedDateTime`. /// The native Rust implementation of `Temporal.ZonedDateTime`.
@ -98,24 +96,21 @@ impl<C: CalendarProtocol, Z: TzProtocol> ZonedDateTime<C, Z> {
// ==== Context based API ==== // ==== Context based API ====
impl<C: CalendarProtocol, Z: TzProtocol> ZonedDateTime<C, Z> { impl<C, Z: TzProtocol> ZonedDateTime<C, Z>
where
C: CalendarProtocol<Context = Z::Context>,
{
/// Returns the `year` value for this `ZonedDateTime`. /// Returns the `year` value for this `ZonedDateTime`.
#[inline] #[inline]
pub fn contextual_year(&self, context: &mut dyn Any) -> TemporalResult<i32> { pub fn contextual_year(&self, context: &mut C::Context) -> TemporalResult<i32> {
let dt = self let dt = self
.tz .tz
.get_datetime_for(&self.instant, &self.calendar, context)?; .get_datetime_for(&self.instant, &self.calendar, context)?;
self.calendar.year(&CalendarDateLike::DateTime(dt), context) self.calendar.year(&CalendarDateLike::DateTime(dt), context)
} }
/// Returns the `year` value for this `ZonedDateTime`.
#[inline]
pub fn year(&self) -> TemporalResult<i32> {
self.contextual_year(&mut ())
}
/// Returns the `month` value for this `ZonedDateTime`. /// Returns the `month` value for this `ZonedDateTime`.
pub fn contextual_month(&self, context: &mut dyn Any) -> TemporalResult<u8> { pub fn contextual_month(&self, context: &mut C::Context) -> TemporalResult<u8> {
let dt = self let dt = self
.tz .tz
.get_datetime_for(&self.instant, &self.calendar, context)?; .get_datetime_for(&self.instant, &self.calendar, context)?;
@ -123,14 +118,8 @@ impl<C: CalendarProtocol, Z: TzProtocol> ZonedDateTime<C, Z> {
.month(&CalendarDateLike::DateTime(dt), context) .month(&CalendarDateLike::DateTime(dt), context)
} }
/// Returns the `month` value for this `ZonedDateTime`.
#[inline]
pub fn month(&self) -> TemporalResult<u8> {
self.contextual_month(&mut ())
}
/// Returns the `monthCode` value for this `ZonedDateTime`. /// Returns the `monthCode` value for this `ZonedDateTime`.
pub fn contextual_month_code(&self, context: &mut dyn Any) -> TemporalResult<TinyStr4> { pub fn contextual_month_code(&self, context: &mut C::Context) -> TemporalResult<TinyStr4> {
let dt = self let dt = self
.tz .tz
.get_datetime_for(&self.instant, &self.calendar, context)?; .get_datetime_for(&self.instant, &self.calendar, context)?;
@ -138,102 +127,61 @@ impl<C: CalendarProtocol, Z: TzProtocol> ZonedDateTime<C, Z> {
.month_code(&CalendarDateLike::DateTime(dt), context) .month_code(&CalendarDateLike::DateTime(dt), context)
} }
/// Returns the `monthCode` value for this `ZonedDateTime`.
#[inline]
pub fn month_code(&self) -> TemporalResult<TinyStr4> {
self.contextual_month_code(&mut ())
}
/// Returns the `day` value for this `ZonedDateTime`. /// Returns the `day` value for this `ZonedDateTime`.
pub fn contextual_day(&self, context: &mut dyn Any) -> TemporalResult<u8> { pub fn contextual_day(&self, context: &mut C::Context) -> TemporalResult<u8> {
let dt = self let dt = self
.tz .tz
.get_datetime_for(&self.instant, &self.calendar, context)?; .get_datetime_for(&self.instant, &self.calendar, context)?;
self.calendar.day(&CalendarDateLike::DateTime(dt), context) self.calendar.day(&CalendarDateLike::DateTime(dt), context)
} }
/// Returns the `day` value for this `ZonedDateTime`.
pub fn day(&self) -> TemporalResult<u8> {
self.contextual_day(&mut ())
}
/// Returns the `hour` value for this `ZonedDateTime`. /// Returns the `hour` value for this `ZonedDateTime`.
pub fn contextual_hour(&self, context: &mut dyn Any) -> TemporalResult<u8> { pub fn contextual_hour(&self, context: &mut C::Context) -> TemporalResult<u8> {
let dt = self let dt = self
.tz .tz
.get_datetime_for(&self.instant, &self.calendar, context)?; .get_datetime_for(&self.instant, &self.calendar, context)?;
Ok(dt.hour()) Ok(dt.hour())
} }
/// Returns the `hour` value for this `ZonedDateTime`.
pub fn hour(&self) -> TemporalResult<u8> {
self.contextual_hour(&mut ())
}
/// Returns the `minute` value for this `ZonedDateTime`. /// Returns the `minute` value for this `ZonedDateTime`.
pub fn contextual_minute(&self, context: &mut dyn Any) -> TemporalResult<u8> { pub fn contextual_minute(&self, context: &mut C::Context) -> TemporalResult<u8> {
let dt = self let dt = self
.tz .tz
.get_datetime_for(&self.instant, &self.calendar, context)?; .get_datetime_for(&self.instant, &self.calendar, context)?;
Ok(dt.minute()) Ok(dt.minute())
} }
/// Returns the `minute` value for this `ZonedDateTime`.
pub fn minute(&self) -> TemporalResult<u8> {
self.contextual_minute(&mut ())
}
/// Returns the `second` value for this `ZonedDateTime`. /// Returns the `second` value for this `ZonedDateTime`.
pub fn contextual_second(&self, context: &mut dyn Any) -> TemporalResult<u8> { pub fn contextual_second(&self, context: &mut C::Context) -> TemporalResult<u8> {
let dt = self let dt = self
.tz .tz
.get_datetime_for(&self.instant, &self.calendar, context)?; .get_datetime_for(&self.instant, &self.calendar, context)?;
Ok(dt.second()) Ok(dt.second())
} }
/// Returns the `second` value for this `ZonedDateTime`.
pub fn second(&self) -> TemporalResult<u8> {
self.contextual_second(&mut ())
}
/// Returns the `millisecond` value for this `ZonedDateTime`. /// Returns the `millisecond` value for this `ZonedDateTime`.
pub fn contextual_millisecond(&self, context: &mut dyn Any) -> TemporalResult<u16> { pub fn contextual_millisecond(&self, context: &mut C::Context) -> TemporalResult<u16> {
let dt = self let dt = self
.tz .tz
.get_datetime_for(&self.instant, &self.calendar, context)?; .get_datetime_for(&self.instant, &self.calendar, context)?;
Ok(dt.millisecond()) Ok(dt.millisecond())
} }
/// Returns the `millisecond` value for this `ZonedDateTime`.
pub fn millisecond(&self) -> TemporalResult<u16> {
self.contextual_millisecond(&mut ())
}
/// Returns the `microsecond` value for this `ZonedDateTime`. /// Returns the `microsecond` value for this `ZonedDateTime`.
pub fn contextual_microsecond(&self, context: &mut dyn Any) -> TemporalResult<u16> { pub fn contextual_microsecond(&self, context: &mut C::Context) -> TemporalResult<u16> {
let dt = self let dt = self
.tz .tz
.get_datetime_for(&self.instant, &self.calendar, context)?; .get_datetime_for(&self.instant, &self.calendar, context)?;
Ok(dt.millisecond()) Ok(dt.millisecond())
} }
/// Returns the `microsecond` value for this `ZonedDateTime`.
pub fn microsecond(&self) -> TemporalResult<u16> {
self.contextual_microsecond(&mut ())
}
/// Returns the `nanosecond` value for this `ZonedDateTime`. /// Returns the `nanosecond` value for this `ZonedDateTime`.
pub fn contextual_nanosecond(&self, context: &mut dyn Any) -> TemporalResult<u16> { pub fn contextual_nanosecond(&self, context: &mut C::Context) -> TemporalResult<u16> {
let dt = self let dt = self
.tz .tz
.get_datetime_for(&self.instant, &self.calendar, context)?; .get_datetime_for(&self.instant, &self.calendar, context)?;
Ok(dt.nanosecond()) Ok(dt.nanosecond())
} }
/// Returns the `nanosecond` value for this `ZonedDateTime`.
pub fn nanosecond(&self) -> TemporalResult<u16> {
self.contextual_nanosecond(&mut ())
}
} }
#[cfg(test)] #[cfg(test)]
@ -259,12 +207,12 @@ mod tests {
) )
.unwrap(); .unwrap();
assert_eq!(zdt.year().unwrap(), 2023); assert_eq!(zdt.contextual_year(&mut ()).unwrap(), 2023);
assert_eq!(zdt.month().unwrap(), 11); assert_eq!(zdt.contextual_month(&mut ()).unwrap(), 11);
assert_eq!(zdt.day().unwrap(), 30); assert_eq!(zdt.contextual_day(&mut ()).unwrap(), 30);
assert_eq!(zdt.hour().unwrap(), 1); assert_eq!(zdt.contextual_hour(&mut ()).unwrap(), 1);
assert_eq!(zdt.minute().unwrap(), 49); assert_eq!(zdt.contextual_minute(&mut ()).unwrap(), 49);
assert_eq!(zdt.second().unwrap(), 12); assert_eq!(zdt.contextual_second(&mut ()).unwrap(), 12);
let zdt_minus_five = ZonedDateTime::<(), ()>::new( let zdt_minus_five = ZonedDateTime::<(), ()>::new(
nov_30_2023_utc, nov_30_2023_utc,
@ -276,11 +224,11 @@ mod tests {
) )
.unwrap(); .unwrap();
assert_eq!(zdt_minus_five.year().unwrap(), 2023); assert_eq!(zdt_minus_five.contextual_year(&mut ()).unwrap(), 2023);
assert_eq!(zdt_minus_five.month().unwrap(), 11); assert_eq!(zdt_minus_five.contextual_month(&mut ()).unwrap(), 11);
assert_eq!(zdt_minus_five.day().unwrap(), 29); assert_eq!(zdt_minus_five.contextual_day(&mut ()).unwrap(), 29);
assert_eq!(zdt_minus_five.hour().unwrap(), 20); assert_eq!(zdt_minus_five.contextual_hour(&mut ()).unwrap(), 20);
assert_eq!(zdt_minus_five.minute().unwrap(), 49); assert_eq!(zdt_minus_five.contextual_minute(&mut ()).unwrap(), 49);
assert_eq!(zdt_minus_five.second().unwrap(), 12); assert_eq!(zdt_minus_five.contextual_second(&mut ()).unwrap(), 12);
} }
} }

Loading…
Cancel
Save