Skip to content
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

Temporal bindings #76

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Webapi.res
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module ReadableStream = Webapi__ReadableStream
module IntersectionObserver = Webapi__IntersectionObserver
module ResizeObserver = Webapi__ResizeObserver
module Url = Webapi__Url
module Temporal = Webapi__Temporal
module WebSocket = Webapi__WebSocket

type rafId
Expand Down
1 change: 1 addition & 0 deletions src/Webapi/Temporal/Webapi__Temporal__Calendar.res
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
type t = Webapi__Temporal__Types.calendar
22 changes: 22 additions & 0 deletions src/Webapi/Temporal/Webapi__Temporal__Difference.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module DifferenceOptions = {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This submodule doesn't seem to add anything? I think it would work just as well without the submodule wrapper.

type t

type durationUnit = [
| #auto
| #hour
| #minute
| #second
| #millisecond
| #microsecond
| #nanosecond
]

@obj
external make: (
~largestUnit: durationUnit=?,
~smallestUnit: durationUnit=?,
~roundingIncrement: int=?,
~roundingMode: [#halfExpand | #ceil | #trunc | #floor]=?,
unit
) => t = ""
}
105 changes: 105 additions & 0 deletions src/Webapi/Temporal/Webapi__Temporal__Duration.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
type t = Webapi__Temporal__Types.duration

@new
external make: (
~years: int=?,
~months: int=?,
~weeks: int=?,
~days: int=?,
~hours: int=?,
~minutes: int=?,
~seconds: int=?,
~milliseconds: int=?,
~microseconds: int=?,
~nanoseconds: int=?,
unit,
) => t = "Temporal.Duration"

@scope("Temporal.Duration") @val external fromString: string => t = "from"
@scope("Temporal.Duration") @val external compare: (t, t) => int = "compare"
@scope("Temporal.Duration") @val
external compareRelativeToPlainDate: (t, {"relativeTo": Webapi__Temporal__Types.plainDate}) => int =
"compare"
@scope("Temporal.Duration") @val
external compareRelativeToZonedDateTime: (
t,
{"relativeTo": Webapi__Temporal__Types.zonedDateTime},
) => int = "compare"

@get external years: t => int = "years"
@get external months: t => int = "months"
@get external days: t => int = "days"
@get external hours: t => int = "hours"
@get external minutes: t => int = "minutes"
@get external seconds: t => int = "seconds"
@get external milliseconds: t => int = "milliseconds"
@get external microseconds: t => int = "microseconds"
@get external nanoseconds: t => int = "nanoseconds"
@get external sign: t => int = "sign"
@get external blank: t => bool = "blank"
// TODO: Add `with` binding
@send external add: (t, t) => t = "add"
@send
external addRelativeToPlainDate: (t, t, {"relativeTo": Webapi__Temporal__Types.plainDate}) => t =
"add"
@send
external addRelativeToZonedDateTime: (
t,
t,
{"relativeTo": Webapi__Temporal__Types.zonedDateTime},
) => t = "add"
@send external subtract: (t, t) => t = "subtract"
@send
external subtractRelativeToPlainDate: (
t,
t,
{"relativeTo": Webapi__Temporal__Types.plainDate},
) => t = "subtract"
@send
external subtractRelativeToZonedDateTime: (
t,
t,
{"relativeTo": Webapi__Temporal__Types.zonedDateTime},
) => t = "subtract"
@send external negated: t => t = "negated"
@send external abs: t => t = "abs"

type roundTo = [
| #day
| #hour
| #minute
| #second
| #millisecond
| #microsecond
| #nanosecond
]

@send external round: (t, ~to: roundTo) => t = "round"
// TODO: roundWithOptions. Tough because relativeTo can be either a PlainDate or ZonedDateTime
@send
external total: (
t,
[#hour | #minute | #second | #millisecond | #microsecond | #nanosecond],
) => float = "total"
// TODO: totalWithOptions. Tough because relativeTo can be either a PlainDate or ZonedDateTime

module ToStringOptions = {
type t

@obj
external make: (
~fractionalSecondDigits: [#auto | #0 | #1 | #2 | #3 | #4 | #5 | #6 | #7 | #8 | #9]=?,
~smallestUnit: [
| #second
| #millisecond
| #microsecond
| #nanosecond
]=?,
~roundingMode: [#halfExpand | #ceil | #trunc | #floor]=?,
unit
) => t = ""
}

@send external toString: t => string = "toString"
@send external toStringWithOptions: (t, ToStringOptions.t) => string = "toString"
// TODO: toLocaleString, need Intl bindings
92 changes: 92 additions & 0 deletions src/Webapi/Temporal/Webapi__Temporal__Instant.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
type t = Webapi__Temporal__Types.instant

// @new external make: BigInt.t => t = "Temporal.Instant"
@scope("Temporal.Instant") @val external fromString: string => t = "from"
@scope("Temporal.Instant") @val external fromInstant: t => t = "from"
@scope("Temporal.Instant") @val external fromEpochSeconds: float => t = "fromEpochSeconds"
@scope("Temporal.Instant") @val
external fromEpochMilliseconds: float => t = "fromEpochMilliseconds"
// @scope("Temporal.Instant") @val external fromEpochMicroseconds: BigInt.t => t = "fromEpochMicroseconds"
// @scope("Temporal.Instant") @val external fromEpochNanoseconds: BigInt.t => t = "fromEpochNanoseconds"
@scope("Temporal.Instant") @val external compare: (t, t) => int = "compare"
@scope("Temporal.Instant") @val external compareStrings: (string, string) => int = "compare"

@get external epochSeconds: t => float = "epochSeconds"
@get external epochMilliseconds: t => float = "epochMilliseconds"
// @get external epochMicroseconds: t => BigInt.t = "epochMicroseconds"
// @get external epochNanoseconds: t => BigInt.t = "epochNanoseconds"
@send
external toZonedDateTimeISO: (
t,
Webapi__Temporal__Types.timeZone,
) => Webapi__Temporal__ZonedDateTime.t = "toZonedDateTimeISO"
@send
external toZonedDateTime: (
t,
{"timeZone": Webapi__Temporal__Types.timeZone, "calendar": Webapi__Temporal__Types.calendar},
) => Webapi__Temporal__ZonedDateTime.t = "toZonedDateTime"
@send external add: (t, Webapi__Temporal__Types.duration) => t = "add"
@send external subtract: (t, Webapi__Temporal__Types.duration) => t = "subtract"

@send external until: (t, t) => Webapi__Temporal__Types.duration = "until"
@send
external untilWithOptions: (
t,
t,
Webapi__Temporal__Difference.DifferenceOptions.t,
) => Webapi__Temporal__Types.duration = "until"
@send external since: (t, t) => Webapi__Temporal__Types.duration = "since"
@send
external sinceWithOptions: (
t,
t,
Webapi__Temporal__Difference.DifferenceOptions.t,
) => Webapi__Temporal__Types.duration = "since"

type roundTo = [
| #hour
| #minute
| #second
| #millisecond
| #microsecond
| #nanosecond
]

module RoundOptions = {
type t

@obj
external make: (
~smallestUnit: roundTo,
~roundingIncrement: int=?,
~roundingMode: [#halfExpand | #ceil | #trunc | #floor]=?,
unit
) => t = ""
}

@send external round: (t, ~to: roundTo) => t = "round"
@send external roundWithOptions: (t, RoundOptions.t) => t = "round"
Comment on lines +55 to +68
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're careful the sub-module can be avoided for simple cases like this. I know the rest of the library does it this way but once we look at modernising the API (and reducing runtime code generation) I might try to rename some of the make submodule methods to be named directly, instead of encapsulated:

Suggested change
module RoundOptions = {
type t
@obj
external make: (
~smallestUnit: roundTo,
~roundingIncrement: int=?,
~roundingMode: [#halfExpand | #ceil | #trunc | #floor]=?,
unit
) => t = ""
}
@send external round: (t, ~to: roundTo) => t = "round"
@send external roundWithOptions: (t, RoundOptions.t) => t = "round"
type roundOptions
@obj
external roundOptions: (
~smallestUnit: roundTo,
~roundingIncrement: int=?,
~roundingMode: [#halfExpand | #ceil | #trunc | #floor]=?,
unit
) => roundOptions = ""
@send external round: (t, ~to: roundTo) => t = "round"
@send external roundWithOptions: (t, roundOptions) => t = "round"

And so on for the other submodules you've added in this PR. In this style using it becomes value->Instant.roundWithOptions(Instant.roundOptions(~smallestUnit=#hour, ())).

Although to be fair by the time we get to v2 we might have ReScript 10 available, and if the structural typing change in master works as well as we hope the entire @obj system will be replaced.

@send external equals: (t, t) => bool = "equals"

module ToStringOptions = {
type t

@obj
external make: (
~timeZone: Webapi__Temporal__Types.timeZone=?,
~fractionalSecondDigits: [#auto | #0 | #1 | #2 | #3 | #4 | #5 | #6 | #7 | #8 | #9]=?,
~smallestUnit: [
| #minute
| #second
| #millisecond
| #microsecond
| #nanosecond
]=?,
~roundingMode: [#halfExpand | #ceil | #trunc | #floor]=?,
unit
) => t = ""
}

@send external toString: t => string = "toString"
@send external toStringWithOptions: (t, ToStringOptions.t) => string = "toString"
// TODO: toLocaleString, need Intl bindings
49 changes: 49 additions & 0 deletions src/Webapi/Temporal/Webapi__Temporal__Now.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
@scope("Temporal.Now") @val
external zonedDateTimeISO: unit => Webapi__Temporal__Types.zonedDateTime = "zonedDateTimeISO"
@scope("Temporal.Now") @val
external zonedDateTimeISOWithTimeZone: Webapi__Temporal__Types.timeZone => Webapi__Temporal__Types.zonedDateTime =
"zonedDateTimeISO"
@scope("Temporal.Now") @val
external zonedDateTime: Webapi__Temporal__Types.calendar => Webapi__Temporal__Types.zonedDateTime =
"zonedDateTime"
@scope("Temporal.Now") @val
external zonedDateTimeWithTimeZone: (
Webapi__Temporal__Types.calendar,
Webapi__Temporal__Types.timeZone,
) => Webapi__Temporal__Types.zonedDateTime = "zonedDateTimeWithTimeZone"
@scope("Temporal.Now") @val external instant: unit => Webapi__Temporal__Types.instant = "instant"
@scope("Temporal.Now") @val external timeZone: unit => Webapi__Temporal__Types.timeZone = "timeZone"

@scope("Temporal.Now") @val
external plainDateTimeISO: unit => Webapi__Temporal__Types.plainDateTime = "plainDateTimeISO"
@scope("Temporal.Now") @val
external plainDateTimeISOWithTimeZone: Webapi__Temporal__Types.timeZone => Webapi__Temporal__Types.plainDateTime =
"plainDateTimeISO"
@scope("Temporal.Now") @val
external plainDateTime: Webapi__Temporal__Types.calendar => Webapi__Temporal__Types.plainDateTime =
"plainDateTime"
@scope("Temporal.Now") @val
external plainDateTimeWithTimeZone: (
Webapi__Temporal__Types.calendar,
Webapi__Temporal__Types.timeZone,
) => Webapi__Temporal__Types.plainDateTime = "plainDateTime"

@scope("Temporal.Now") @val
external plainDateISO: unit => Webapi__Temporal__Types.plainDate = "plainDateISO"
@scope("Temporal.Now") @val
external plainDateISOWithTimeZone: Webapi__Temporal__Types.timeZone => Webapi__Temporal__Types.plainDate =
"plainDateISO"
@scope("Temporal.Now") @val
external plainDate: Webapi__Temporal__Types.calendar => Webapi__Temporal__Types.plainDate =
"plainDate"
@scope("Temporal.Now") @val
external plainDateWithTimeZone: (
Webapi__Temporal__Types.calendar,
Webapi__Temporal__Types.timeZone,
) => Webapi__Temporal__Types.plainDate = "plainDate"

@scope("Temporal.Now") @val
external plainTimeISO: unit => Webapi__Temporal__Types.plainTime = "plainTimeISO"
@scope("Temporal.Now") @val
external plainTimeISOWithTimeZone: Webapi__Temporal__Types.timeZone => Webapi__Temporal__Types.plainTime =
"plainTimeISO"
Loading