Browse Source

Swap to Duration::round from temporal_rs (#3731)

* Swap to Duration::round from temporal_rs

* Clean up round method and impl From for RoundingMode enum

* Fix build failure

* Fix clippy error

* Respond to comments

* Remove commented line
pull/3762/head
Matthew Stone 2 months ago committed by GitHub
parent
commit
48750f361a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 35
      core/engine/src/builtins/temporal/duration/mod.rs
  2. 35
      core/engine/src/builtins/temporal/mod.rs
  3. 13
      core/engine/src/builtins/temporal/options.rs

35
core/engine/src/builtins/temporal/duration/mod.rs

@ -2,7 +2,7 @@
use crate::{
builtins::{
options::{get_option, get_options_object, RoundingMode},
options::{get_option, get_options_object},
BuiltInBuilder, BuiltInConstructor, BuiltInObject, IntrinsicObject,
},
context::intrinsics::{Intrinsics, StandardConstructor, StandardConstructors},
@ -15,7 +15,10 @@ use crate::{
};
use boa_gc::{Finalize, Trace};
use boa_profiler::Profiler;
use temporal_rs::{components::Duration as InnerDuration, options::TemporalUnit};
use temporal_rs::{
components::Duration as InnerDuration,
options::{RelativeTo, TemporalRoundingMode, TemporalUnit},
};
use super::{
options::{get_temporal_rounding_increment, get_temporal_unit, TemporalUnitGroup},
@ -590,7 +593,6 @@ impl Duration {
.into())
}
// TODO: Migrate to `temporal_rs's Duration::round`
/// 7.3.20 `Temporal.Duration.prototype.round ( roundTo )`
pub(crate) fn round(
this: &JsValue,
@ -599,7 +601,7 @@ impl Duration {
) -> JsResult<JsValue> {
// 1. Let duration be the this value.
// 2. Perform ? RequireInternalSlot(duration, [[InitializedTemporalDuration]]).
let _duration = this
let duration = this
.as_object()
.and_then(JsObject::downcast_ref::<Self>)
.ok_or_else(|| {
@ -651,15 +653,15 @@ impl Duration {
// 10. Let relativeToRecord be ? ToRelativeTemporalObject(roundTo).
// 11. Let zonedRelativeTo be relativeToRecord.[[ZonedRelativeTo]].
// 12. Let plainRelativeTo be relativeToRecord.[[PlainRelativeTo]].
let (_plain_relative_to, _zoned_relative_to) =
let (plain_relative_to, zoned_relative_to) =
super::to_relative_temporal_object(&round_to, context)?;
// 13. Let roundingIncrement be ? ToTemporalRoundingIncrement(roundTo).
let _rounding_increment = get_temporal_rounding_increment(&round_to, context)?;
let rounding_increment = get_temporal_rounding_increment(&round_to, context)?;
// 14. Let roundingMode be ? ToTemporalRoundingMode(roundTo, "halfExpand").
let _rounding_mode = get_option(&round_to, utf16!("roundingMode"), context)?
.unwrap_or(RoundingMode::HalfExpand);
let rounding_mode =
get_option::<TemporalRoundingMode>(&round_to, utf16!("roundingMode"), context)?;
// 15. Let smallestUnit be ? GetTemporalUnit(roundTo, "smallestUnit", datetime, undefined).
let smallest_unit = get_temporal_unit(
@ -678,11 +680,18 @@ impl Duration {
.with_message("smallestUnit or largestUnit must be present.")
.into());
}
// NOTE:
Err(JsNativeError::range()
.with_message("not yet implemented.")
.into())
let rounded_duration = duration.inner.round(
rounding_increment,
smallest_unit,
largest_unit,
rounding_mode,
&RelativeTo {
date: plain_relative_to.as_ref(),
zdt: zoned_relative_to.as_ref(),
},
context,
)?;
create_temporal_duration(rounded_duration, None, context).map(Into::into)
}
/// 7.3.21 `Temporal.Duration.prototype.total ( totalOf )`

35
core/engine/src/builtins/temporal/mod.rs

@ -31,14 +31,18 @@ use crate::{
builtins::{iterable::IteratorRecord, BuiltInBuilder, BuiltInObject, IntrinsicObject},
context::intrinsics::Intrinsics,
js_string,
property::Attribute,
property::{Attribute, PropertyKey},
realm::Realm,
string::common::StaticJsStrings,
value::Type,
Context, JsBigInt, JsNativeError, JsObject, JsResult, JsString, JsSymbol, JsValue,
Context, JsBigInt, JsError, JsNativeError, JsObject, JsResult, JsString, JsSymbol, JsValue,
};
use boa_macros::utf16;
use boa_profiler::Profiler;
use temporal_rs::NS_PER_DAY;
use temporal_rs::{
components::{Date as TemporalDate, ZonedDateTime as TemporalZonedDateTime},
NS_PER_DAY,
};
// TODO: Remove in favor of `temporal_rs`
pub(crate) fn ns_max_instant() -> JsBigInt {
@ -238,14 +242,27 @@ pub(crate) fn _iterator_to_list_of_types(
// 13.17 `ValidateTemporalRoundingIncrement ( increment, dividend, inclusive )`
// Moved to temporal_rs
type RelativeTemporalObjectResult = JsResult<(
Option<TemporalDate<JsObject>>,
Option<TemporalZonedDateTime<JsObject, JsCustomTimeZone>>,
)>;
/// 13.21 `ToRelativeTemporalObject ( options )`
pub(crate) fn to_relative_temporal_object(
_options: &JsObject,
_context: &mut Context,
) -> JsResult<(Option<PlainDate>, Option<ZonedDateTime>)> {
Err(JsNativeError::range()
.with_message("not yet implemented.")
.into())
options: &JsObject,
context: &mut Context,
) -> RelativeTemporalObjectResult {
let relative_to = options.get(PropertyKey::from(utf16!("relativeTo")), context)?;
let plain_date = match relative_to {
JsValue::String(relative_to_str) => Some(relative_to_str.into()),
JsValue::Object(relative_to_obj) => Some(relative_to_obj.into()),
_ => None,
}
.map(|plane_date| Ok::<_, JsError>(to_temporal_date(&plane_date, None, context)?.inner))
.transpose()?;
// TODO: Implement TemporalZonedDateTime conversion when ZonedDateTime is implemented
Ok((plain_date, None))
}
// 13.22 `LargerOfTwoTemporalUnits ( u1, u2 )`

13
core/engine/src/builtins/temporal/options.rs

@ -24,15 +24,14 @@ use temporal_rs::options::{
pub(crate) fn get_temporal_rounding_increment(
options: &JsObject,
context: &mut Context,
) -> JsResult<u32> {
) -> JsResult<Option<f64>> {
// 1. Let increment be ? GetOption(normalizedOptions, "roundingIncrement", "number", undefined, 1𝔽).
let value = options.get(js_string!("roundingIncrement"), context)?;
let increment = if value.is_undefined() {
1.0
} else {
value.to_number(context)?
};
if value.is_undefined() {
return Ok(None);
}
let increment = value.to_number(context)?;
// 2. If increment is not finite, throw a RangeError exception.
if !increment.is_finite() {
@ -52,7 +51,7 @@ pub(crate) fn get_temporal_rounding_increment(
}
// 5. Return integerIncrement.
Ok(integer_increment as u32)
Ok(Some(integer_increment))
}
/// Gets the `TemporalUnit` from an options object.

Loading…
Cancel
Save