-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement MonthCode
, PartialDate
, and Date::with
#89
Conversation
PrepareTemporalFields has always been slightly weird. I am trying to see if it can be simplified if custom calendars are not a thing. |
I think it definitely can be split apart. Does the split between a "PartialDateLike" (so to speak) in |
Those two operations were combined into PrepareTemporalFields because in both cases, you need to do property Gets on the object (partial date, date-like property bag, or PlainDate). Without custom calendars, you don't need to do the property Gets anymore on PlainDate. But the handling of partial date vs date-like property bag is still very similar. I'm not yet sure of what is going to be the best way to simplify it. |
Yeah, the issue I'm running into is that it has to be representable via the type system, if possible, in order to implement in Honestly, assuming I'm readying the functionality correctly. This specific split might be easier to reason about than the previous PrepareTemporalFields. Or it could be off base of the intended functionality. I should probably add some unit tests 😅 |
} | ||
|
||
impl MonthCode { | ||
pub fn as_str(&self) -> &str { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will these not change in different calendars? Aren't there more month codes in the chinese calendar? such as https://tc39.es/proposal-intl-era-monthcode/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I realized that earlier. I was sort of thinking we could just expand the enum, but that's probably not sufficient either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this structure is fine for now and we can refactor it to support more in future? What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think if you don't have a "leap" flag in the month code then it probably doesn't make sense to have M13... AFAIK no calendars have an M13, if there is a thirteenth month it's always one of M00L through M12L (or maybe M01L through M11L; it's unclear whether M00L and M12L actually exist)
src/components/calendar.rs
Outdated
) -> TemporalResult<Vec<TemporalFieldKey>> { | ||
let mut ignored_keys = Vec::default(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this vec have a minimal capacity? I think right now it will hold 3 keys before reallocating
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oooh, potentially. I'll check that!
68a2dd5
to
18173dc
Compare
src/components/date.rs
Outdated
pub struct PartialDate { | ||
pub(crate) year: Option<i32>, | ||
pub(crate) month: Option<i32>, | ||
pub(crate) month_code: Option<MonthCode>, | ||
pub(crate) day: Option<i32>, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I said in the Temporal meeting about the requirement being "day AND (month OR monthCode) AND (year OR (era AND eraYear))" reminded me that this should probably have optional fields for era
and era_year
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, good point. I had meant to add those in one the update and forgot too.
f9b54e8
to
b348d78
Compare
This PR refactors `TemporalFields` into `CalendarFields`. I'm leaving it as a draft for now as I want to run plug this into Boa and run some tests beforehand. General Context: This builds on the work from #89 and #92. With the partials implemented for the `with` methods. The values that would be provided can now be accounted for. Primarily, the time fields really didn't need to exist in the `TemporalFields` representation anymore (along with the TimeZone and offset which will probably be living on the `PartialZonedDateTime`). Furthermore, the partials were now handling the `undefined` case of the fields, so the calendar specific fields no longer needed to be an `Option`. In general, I also just think that this is a better native representation of the fields values in comparison to the previous version. Furthermore, this PR also implements better handling for Era and Month Codes according to the [Intl era and monthCode proposal](https://tc39.es/proposal-intl-era-monthcode/#sec-temporal-isvalidmonthecodeforcalendar). There are a couple points where feedback/bike-shedding would definitely be appreciated. I think the method names in `calendar_types.rs` are getting a bit unyielding. I am also a bit worried about introducing the `CalendarMethods` trait, but I do think it makes the ergonomics around passing `Date`, `DateTime`, and, eventually, `ZonedDateTime` as a fallback convenient. cc: @sffc
So the title basically says it all as far as implementation. That being said, there's a lot of interpretation going into this that I'd like feedback on if possible, and it could be the right direction or it could be the wrong direction (although I'm leaning the former over the latter).
The main culprit is basically PrepareTemporalFields.
Background for discussion/sanity check:
Up until recently, I basically thought it would be an implementation detail on the engine/interpreter side, but the thing that always bugged me was the
requiredFields
parameter, being either a List or PARTIAL. We could probably do that to specification, but we might be providing something likeSome(Vec::default())
as an argument, and it basically just felt clunky.After the recent
TemporalFields
update, I went to implement theTemporalFields
portion of thetoX
abstract ops in Boa and realized that PARTIAL is never called in thetoX
operations, and it's actually exclusively called inwith
methods. We already have a sort of precedence for partials withPartialDuration
.There's some benefits to this: we can have a with method on the native rust side, ideally the complexity that exists in
PrepareTemporalFields
can be made a bit easier to reason about.Potential negatives: we might end up deviating from the specification as far as the order of when errors are thrown and observability (TBD...potentially a total non-issue) and this is probably opening up a can of worms around what would be the ideal API for a
PartialDate
,PartialDateTime
, andPartialTime
.That all being said, I think the benefits do most likely outweigh any negatives, and it would be really cool to have
with
method implementations. I'm just not entirely sure around the API.Also, there's an addition of a
MonthCode
enum to makeFrom<X> for TemporalFields
implementations easier.