|
| 1 | +# Temporal API Design |
| 2 | + |
| 3 | +This design hopes to layout an initial concept to adapting the `Temporal` API for Rust. The layout |
| 4 | +was broadly mentioned in a previous PR earlier in the development of `Temporal`. This write up is to |
| 5 | +mainly overview the API, and provide context to any potential contributors. |
| 6 | + |
| 7 | +There are three incredibly important points to keep in mind during the design and implementation |
| 8 | + |
| 9 | +1. This library should empower any language engine to implement `Temporal` to a high degree of fidelity. |
| 10 | +2. This library should be able to provide a non-engine API consumable by any potential user. |
| 11 | + |
| 12 | +Admittedly, as this library is being designed for use in a `JavaScript` engine. One takes priority, |
| 13 | +but that should not completely overshadow the two. |
| 14 | + |
| 15 | +The largest concerns come around the implementation for both `Calendar` and `TimeZone` (aka, `CalendarSlot` |
| 16 | +and `TimeZoneSlot`). |
| 17 | + |
| 18 | +Date is defined (broadly) as: |
| 19 | + |
| 20 | +```rust |
| 21 | + |
| 22 | +// In `Boa`, Date<C> is represented as Date<JsObject> |
| 23 | +struct Date<C: CalendarProtocol> { |
| 24 | + iso: IsoDate, |
| 25 | + calendar: CalendarSlot<C>, |
| 26 | +} |
| 27 | + |
| 28 | +``` |
| 29 | + |
| 30 | +In this instance, C represents any Custom Calendar implementation that is required by the `Temporal` |
| 31 | +specification. It is also fundamental to the design of the library; however, it introduces an |
| 32 | +interesting API concern. |
| 33 | + |
| 34 | +Primarily, what if someone doesn't want to implement a custom Calendar? Well, that's easy, we can just |
| 35 | +use `Date<()>`. That's easy. We've solved the great API crisis! |
| 36 | + |
| 37 | +But there's a catch. To provide utility to engine implementors, `CalendarProtocol` implements a `Context` |
| 38 | +associated type. In order to have access to that context, it needs to be passed in as an argument. |
| 39 | + |
| 40 | +So in an engine, like Boa, this may look like. |
| 41 | + |
| 42 | +```rust |
| 43 | +// Theoretically, fetching a the year value with context. |
| 44 | +let year_value = Date<JsObject>.year(context); |
| 45 | +``` |
| 46 | + |
| 47 | +But this API, makes the non-engine API just that much more cumbersome. |
| 48 | + |
| 49 | +```rust |
| 50 | +// A user fetching a year value. |
| 51 | +let year_value = Date<()>.year(&mut ()); |
| 52 | +``` |
| 53 | + |
| 54 | +There is also the chance that some user WANTS to implement a custom calendar, but does NOT need any `Context`. |
| 55 | + |
| 56 | +```rust |
| 57 | +let year_value = Date<CustomCalendar>.year(&mut ()); |
| 58 | +``` |
| 59 | + |
| 60 | +The API in this instance is not necessarily bad, per se. It's just it could be better for non-engine consumers. |
| 61 | + |
| 62 | +In order to address this issue, this design concept would require that any function that needs a `Context` argument |
| 63 | +clearly labels itself as such. |
| 64 | + |
| 65 | +```rust |
| 66 | +let year_1 = Date<()>.year(); |
| 67 | +let year_2 = Date<()>.year_with_context(&mut ()); |
| 68 | +``` |
0 commit comments