@@ -8,13 +8,22 @@ pub mod instant;
88pub mod options;
99pub mod plain_time;
1010
11+ use temporal_rs:: options:: { DifferenceSettings , RoundingMode , Unit , UnitGroup } ;
12+
1113use crate :: {
1214 ecmascript:: {
1315 builders:: ordinary_object_builder:: OrdinaryObjectBuilder ,
14- execution:: { Agent , Realm } ,
15- types:: { BUILTIN_STRING_MEMORY , IntoValue } ,
16+ builtins:: temporal:: {
17+ instant:: instant_prototype:: { DefaultOption , get_temporal_unit_valued_option} ,
18+ options:: { get_rounding_increment_option, get_rounding_mode_option} ,
19+ } ,
20+ execution:: { Agent , JsResult , Realm } ,
21+ types:: { BUILTIN_STRING_MEMORY , IntoValue , Object } ,
22+ } ,
23+ engine:: {
24+ context:: { Bindable , GcScope , NoGcScope , trivially_bindable} ,
25+ rootable:: Scopable ,
1626 } ,
17- engine:: context:: NoGcScope ,
1827 heap:: WellKnownSymbolIndexes ,
1928} ;
2029
@@ -68,3 +77,89 @@ impl Temporal {
6877 . build ( ) ;
6978 }
7079}
80+
81+ trivially_bindable ! ( DifferenceSettings ) ;
82+ trivially_bindable ! ( UnitGroup ) ;
83+ trivially_bindable ! ( Unit ) ;
84+
85+ /// [13.42 GetDifferenceSettings ( operation, options, unitGroup, disallowedUnits, fallbackSmallestUnit, smallestLargestDefaultUnit )](https://tc39.es/proposal-temporal/#sec-temporal-getdifferencesettings)
86+ /// The abstract operation GetDifferenceSettings takes arguments operation (since or until),
87+ /// options (an Object), unitGroup (date, time, or datetime), disallowedUnits (a List of Temporal units),
88+ /// fallbackSmallestUnit (a Temporal unit), and smallestLargestDefaultUnit (a Temporal unit) and returns either
89+ /// a normal completion containing a Record with fields [[SmallestUnit]] (a Temporal unit),
90+ /// [[LargestUnit]] (a Temporal unit), [[RoundingMode]] (a rounding mode),
91+ /// and [[RoundingIncrement]] (an integer in the inclusive interval from 1 to 10**9),
92+ /// or a throw completion. It reads unit and rounding options needed by difference operations.
93+ pub ( crate ) fn get_difference_settings < ' gc , const IS_UNTIL : bool > (
94+ agent : & mut Agent ,
95+ options : Object < ' gc > , // options (an Object)
96+ _unit_group : UnitGroup , // unitGroup (date, time, or datetime)
97+ _disallowed_units : Vec < Unit > , // disallowedUnits (todo:a List of Temporal units)
98+ _fallback_smallest_unit : Unit , // fallbackSmallestUnit (a Temporal unit)
99+ _smallest_largest_default_unit : Unit , // smallestLargestDefaultUnit (a Temporal unit)
100+ mut gc : GcScope < ' gc , ' _ > ,
101+ ) -> JsResult < ' gc , DifferenceSettings > {
102+ let _unit_group = _unit_group. bind ( gc. nogc ( ) ) ;
103+ let _disallowed_units = _disallowed_units. bind ( gc. nogc ( ) ) ;
104+ let _fallback_smallest_unit = _fallback_smallest_unit. bind ( gc. nogc ( ) ) ;
105+ let _smallest_largest_default_unit = _smallest_largest_default_unit. bind ( gc. nogc ( ) ) ;
106+
107+ let options = options. scope ( agent, gc. nogc ( ) ) ;
108+ // 1. NOTE: The following steps read options and perform independent validation in alphabetical order.
109+ // 2. Let largestUnit be ? GetTemporalUnitValuedOption(options, "largestUnit", unset).
110+ let largest_unit = get_temporal_unit_valued_option (
111+ agent,
112+ options. get ( agent) ,
113+ BUILTIN_STRING_MEMORY . largestUnit . to_property_key ( ) ,
114+ DefaultOption :: Unset ,
115+ gc. reborrow ( ) ,
116+ )
117+ . unbind ( ) ?
118+ . bind ( gc. nogc ( ) ) ;
119+ // 3. Let roundingIncrement be ? GetRoundingIncrementOption(options).
120+ let rounding_increment =
121+ get_rounding_increment_option ( agent, options. get ( agent) , gc. reborrow ( ) )
122+ . unbind ( ) ?
123+ . bind ( gc. nogc ( ) ) ;
124+ // 4. Let roundingMode be ? GetRoundingModeOption(options, trunc).
125+ let rounding_mode = get_rounding_mode_option (
126+ agent,
127+ options. get ( agent) ,
128+ RoundingMode :: Trunc ,
129+ gc. reborrow ( ) ,
130+ )
131+ . unbind ( ) ?
132+ . bind ( gc. nogc ( ) ) ;
133+ // 5. Let smallestUnit be ? GetTemporalUnitValuedOption(options, "smallestUnit", unset).
134+ let smallest_unit = get_temporal_unit_valued_option (
135+ agent,
136+ options. get ( agent) ,
137+ BUILTIN_STRING_MEMORY . smallestUnit . to_property_key ( ) ,
138+ DefaultOption :: Unset ,
139+ gc. reborrow ( ) ,
140+ )
141+ . unbind ( ) ?
142+ . bind ( gc. nogc ( ) ) ;
143+ // 6. Perform ? ValidateTemporalUnitValue(largestUnit, unitGroup, « auto »).
144+ // 7. If largestUnit is unset, then
145+ // a. Set largestUnit to auto.
146+ // 8. If disallowedUnits contains largestUnit, throw a RangeError exception.
147+ // 9. If operation is since, then
148+ // a. Set roundingMode to NegateRoundingMode(roundingMode).
149+ // 10. Perform ? ValidateTemporalUnitValue(smallestUnit, unitGroup).
150+ // 11. If smallestUnit is unset, then
151+ // a. Set smallestUnit to fallbackSmallestUnit.
152+ // 12. If disallowedUnits contains smallestUnit, throw a RangeError exception.
153+ // 13. Let defaultLargestUnit be LargerOfTwoTemporalUnits(smallestLargestDefaultUnit, smallestUnit).
154+ // 14. If largestUnit is auto, set largestUnit to defaultLargestUnit.
155+ // 15. If LargerOfTwoTemporalUnits(largestUnit, smallestUnit) is not largestUnit, throw a RangeError exception.
156+ // 16. Let maximum be MaximumTemporalDurationRoundingIncrement(smallestUnit).
157+ // 17. If maximum is not unset, perform ? ValidateTemporalRoundingIncrement(roundingIncrement, maximum, false).
158+ // 18. Return the Record { [[SmallestUnit]]: smallestUnit, [[LargestUnit]]: largestUnit, [[RoundingMode]]: roundingMode, [[RoundingIncrement]]: roundingIncrement, }.
159+ let mut diff_settings = temporal_rs:: options:: DifferenceSettings :: default ( ) ;
160+ diff_settings. largest_unit = Some ( largest_unit) ;
161+ diff_settings. smallest_unit = Some ( smallest_unit) ;
162+ diff_settings. rounding_mode = Some ( rounding_mode) ;
163+ diff_settings. increment = Some ( rounding_increment) ;
164+ Ok ( diff_settings)
165+ }
0 commit comments