Compare commits
No commits in common. "main" and "v0.2.3" have entirely different histories.
52 changed files with 2543 additions and 1280 deletions
158
.github/workflows/cd.yml
vendored
158
.github/workflows/cd.yml
vendored
|
|
@ -3,7 +3,7 @@ name: Release
|
|||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
|
|
@ -17,180 +17,78 @@ jobs:
|
|||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
# macOS
|
||||
- target: x86_64-macos
|
||||
os: macos-latest
|
||||
rust-target: x86_64-apple-darwin
|
||||
cross-packages: ""
|
||||
cargo-linker-env: ""
|
||||
cargo-linker: ""
|
||||
- target: aarch64-macos
|
||||
os: macos-latest
|
||||
rust-target: aarch64-apple-darwin
|
||||
cross-packages: ""
|
||||
cargo-linker-env: ""
|
||||
cargo-linker: ""
|
||||
|
||||
# Linux (esbuild tier)
|
||||
- target: x86_64-linux-gnu
|
||||
os: ubuntu-latest
|
||||
rust-target: x86_64-unknown-linux-gnu
|
||||
cross-packages: ""
|
||||
cargo-linker-env: ""
|
||||
cargo-linker: ""
|
||||
- target: aarch64-linux-gnu
|
||||
os: ubuntu-latest
|
||||
rust-target: aarch64-unknown-linux-gnu
|
||||
cross-packages: gcc-aarch64-linux-gnu
|
||||
cargo-linker-env: ""
|
||||
cargo-linker: ""
|
||||
- target: x86-linux-gnu
|
||||
os: ubuntu-latest
|
||||
rust-target: i686-unknown-linux-gnu
|
||||
cross-packages: gcc-i686-linux-gnu
|
||||
cargo-linker-env: ""
|
||||
cargo-linker: ""
|
||||
- target: arm-linux-gnueabihf
|
||||
os: ubuntu-latest
|
||||
rust-target: armv7-unknown-linux-gnueabihf
|
||||
cross-packages: gcc-arm-linux-gnueabihf
|
||||
cargo-linker-env: CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER
|
||||
cargo-linker: arm-linux-gnueabihf-gcc
|
||||
- target: loongarch64-linux-gnu
|
||||
os: ubuntu-latest
|
||||
rust-target: loongarch64-unknown-linux-gnu
|
||||
cross-packages: ""
|
||||
cargo-linker-env: CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNU_LINKER
|
||||
cargo-linker: zig cc -target loongarch64-linux-gnu
|
||||
- target: powerpc64le-linux-gnu
|
||||
os: ubuntu-latest
|
||||
rust-target: powerpc64le-unknown-linux-gnu
|
||||
cross-packages: gcc-powerpc64le-linux-gnu
|
||||
cargo-linker-env: ""
|
||||
cargo-linker: ""
|
||||
- target: riscv64-linux-gnu
|
||||
os: ubuntu-latest
|
||||
rust-target: riscv64gc-unknown-linux-gnu
|
||||
cross-packages: gcc-riscv64-linux-gnu
|
||||
cargo-linker-env: ""
|
||||
cargo-linker: ""
|
||||
- target: s390x-linux-gnu
|
||||
os: ubuntu-latest
|
||||
rust-target: s390x-unknown-linux-gnu
|
||||
cross-packages: gcc-s390x-linux-gnu
|
||||
cargo-linker-env: ""
|
||||
cargo-linker: ""
|
||||
|
||||
# Windows
|
||||
- target: x86_64-windows-gnu
|
||||
os: ubuntu-latest
|
||||
rust-target: x86_64-pc-windows-gnu
|
||||
cross-packages: mingw-w64
|
||||
cargo-linker-env: ""
|
||||
cargo-linker: ""
|
||||
- target: aarch64-windows-gnu
|
||||
os: ubuntu-latest
|
||||
rust-target: aarch64-pc-windows-gnullvm
|
||||
cross-packages: mingw-w64
|
||||
cargo-linker-env: ""
|
||||
cargo-linker: ""
|
||||
- target: x86-windows-gnu
|
||||
os: ubuntu-latest
|
||||
rust-target: i686-pc-windows-gnu
|
||||
cross-packages: mingw-w64
|
||||
cargo-linker-env: ""
|
||||
cargo-linker: ""
|
||||
|
||||
# BSD (esbuild tier; use zig cc as cargo linker)
|
||||
- target: x86_64-freebsd
|
||||
os: ubuntu-latest
|
||||
rust-target: x86_64-unknown-freebsd
|
||||
cross-packages: ""
|
||||
cargo-linker-env: CARGO_TARGET_X86_64_UNKNOWN_FREEBSD_LINKER
|
||||
cargo-linker: zig cc -target x86_64-freebsd
|
||||
- target: x86_64-netbsd
|
||||
os: ubuntu-latest
|
||||
rust-target: x86_64-unknown-netbsd
|
||||
cross-packages: ""
|
||||
cargo-linker-env: CARGO_TARGET_X86_64_UNKNOWN_NETBSD_LINKER
|
||||
cargo-linker: zig cc -target x86_64-netbsd
|
||||
|
||||
# Additional targets
|
||||
- target: wasm32-freestanding
|
||||
os: ubuntu-latest
|
||||
rust-target: wasm32-unknown-unknown
|
||||
cross-packages: ""
|
||||
cargo-linker-env: ""
|
||||
cargo-linker: ""
|
||||
- target: wasm32-wasi
|
||||
os: ubuntu-latest
|
||||
rust-target: wasm32-wasip1
|
||||
cross-packages: ""
|
||||
cargo-linker-env: ""
|
||||
cargo-linker: ""
|
||||
- target: x86_64-linux-musl
|
||||
os: ubuntu-latest
|
||||
rust-target: x86_64-unknown-linux-musl
|
||||
cross-packages: ""
|
||||
cargo-linker-env: ""
|
||||
cargo-linker: ""
|
||||
- target: aarch64-linux-musl
|
||||
os: ubuntu-latest
|
||||
rust-target: aarch64-unknown-linux-musl
|
||||
cross-packages: ""
|
||||
cargo-linker-env: ""
|
||||
cargo-linker: ""
|
||||
|
||||
- target: aarch64-linux-android
|
||||
os: ubuntu-latest
|
||||
rust-target: aarch64-linux-android
|
||||
cross-packages: ""
|
||||
cargo-linker-env: ""
|
||||
cargo-linker: ""
|
||||
- target: aarch64-ios
|
||||
os: macos-latest
|
||||
rust-target: aarch64-apple-ios
|
||||
cross-packages: ""
|
||||
cargo-linker-env: ""
|
||||
cargo-linker: ""
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
|
||||
- name: Setup Zig
|
||||
uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.17.0-dev.1398+cb5635714
|
||||
|
||||
version: 0.17.0-dev.387+31f157d80
|
||||
|
||||
- name: Setup Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
targets: ${{ matrix.rust-target }}
|
||||
|
||||
- name: Install cross-compilers
|
||||
if: matrix.cross-packages != ''
|
||||
- name: Install cross-compilers (Linux-aarch64)
|
||||
if: contains(matrix.target, 'aarch64-linux')
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ${{ matrix.cross-packages }}
|
||||
sudo apt-get install -y gcc-aarch64-linux-gnu
|
||||
|
||||
- name: Install cross-compilers (Windows-mingw)
|
||||
if: contains(matrix.target, 'windows-gnu')
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y mingw-w64
|
||||
|
||||
- name: Build Package
|
||||
run: |
|
||||
if [ -n "${{ matrix.cargo-linker-env }}" ]; then
|
||||
export "${{ matrix.cargo-linker-env }}=${{ matrix.cargo-linker }}"
|
||||
fi
|
||||
cd lib
|
||||
cd pkg/temporal
|
||||
zig build -Dbuild-rust -Dtarget=${{ matrix.target }} -Doptimize=ReleaseSafe
|
||||
|
||||
- name: Package artifact
|
||||
run: |
|
||||
cd lib
|
||||
mkdir -p dist
|
||||
tar -czf "dist/${{ matrix.target }}.tar.gz" -C "zig-out/lib/${{ matrix.target }}" .
|
||||
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.target }}
|
||||
path: lib/dist/${{ matrix.target }}.tar.gz
|
||||
name: lib-${{ matrix.target }}
|
||||
path: pkg/temporal/zig-out/lib/
|
||||
retention-days: 1
|
||||
|
||||
release:
|
||||
|
|
@ -199,18 +97,30 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: dist
|
||||
path: all-libs
|
||||
pattern: lib-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Prepare Release Artifact
|
||||
run: |
|
||||
mkdir -p release/lib
|
||||
cp -r all-libs/* release/lib/
|
||||
cd release
|
||||
tar -czf ../libtemporal.tar.gz lib/
|
||||
zip -r ../libtemporal.zip lib/
|
||||
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: dist/*.tar.gz
|
||||
files: |
|
||||
libtemporal.tar.gz
|
||||
libtemporal.zip
|
||||
generate_release_notes: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
|
|||
75
.github/workflows/ci.yml
vendored
75
.github/workflows/ci.yml
vendored
|
|
@ -2,17 +2,9 @@ name: CI
|
|||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'src/**'
|
||||
- 'lib/**'
|
||||
- 'test/**'
|
||||
- 'build.zig'
|
||||
- 'build.zig.zon'
|
||||
- '.github/workflows/ci.yml'
|
||||
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
|
@ -21,34 +13,59 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
|
||||
# os: [ubuntu-latest, macos-latest]
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Zig
|
||||
uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.17.0-dev.387+31f157d80
|
||||
|
||||
- name: Build project
|
||||
run: zig build
|
||||
|
||||
- name: Verify executable
|
||||
run: |
|
||||
./zig-out/bin/zx --help || echo "Executable built successfully"
|
||||
shell: bash
|
||||
|
||||
- name: Setup Zig
|
||||
uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.17.0-dev.1398+cb5635714
|
||||
|
||||
- name: Build and run project
|
||||
run: cd test && zig build run
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: temporalz-${{ matrix.os }}
|
||||
path: zig-out/
|
||||
retention-days: 1
|
||||
|
||||
test:
|
||||
name: Test (${{ matrix.os }})
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: build
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
|
||||
# os: [ubuntu-latest, macos-latest]
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Zig
|
||||
uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.17.0-dev.387+31f157d80
|
||||
|
||||
- name: Setup Zig
|
||||
uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.17.0-dev.1398+cb5635714
|
||||
- name: Download build artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: temporalz-${{ matrix.os }}
|
||||
path: zig-out/
|
||||
|
||||
- name: Run tests
|
||||
run: zig build test
|
||||
- name: Make executable (Unix)
|
||||
if: runner.os != 'Windows'
|
||||
run: chmod +x zig-out/bin/temporalz
|
||||
|
||||
- name: Run tests
|
||||
run: zig build test
|
||||
55
.github/workflows/docs.yml
vendored
55
.github/workflows/docs.yml
vendored
|
|
@ -1,55 +0,0 @@
|
|||
name: Docs
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'src/**'
|
||||
- 'lib/**'
|
||||
- '.github/workflows/docs.yml'
|
||||
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Zig
|
||||
uses: mlugg/setup-zig@v2
|
||||
with:
|
||||
version: 0.17.0-dev.1398+cb5635714
|
||||
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v5
|
||||
|
||||
- name: Build Docs
|
||||
run: zig build docs
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: ./zig-out/docs
|
||||
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -3,4 +3,8 @@ zig-out
|
|||
zig-pkg
|
||||
target
|
||||
|
||||
.tool-versions
|
||||
lib
|
||||
tmp
|
||||
.DS_Store
|
||||
|
||||
test/test262/polyfill-injected.js
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "test/temporal-test262-runner"]
|
||||
path = test/temporal-test262-runner
|
||||
url = https://github.com/js-temporal/temporal-test262-runner.git
|
||||
1
.tool-versions
Normal file
1
.tool-versions
Normal file
|
|
@ -0,0 +1 @@
|
|||
zig master
|
||||
57
README.md
57
README.md
|
|
@ -6,11 +6,12 @@ A Zig library for working with temporal types based on the [Temporal Standard](h
|
|||
|
||||
Temporalz provides Zig bindings to the Rust-based [temporal_rs](https://github.com/boa-dev/temporal) library for handling dates, times, and durations with proper timezone support.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
- Zig 0.17.0-dev.1398+cb5635714
|
||||
- Zig 0.17.0-dev.387+31f157d80
|
||||
- Rust toolchain (only required if [prebuilt staticlibs](#prebuilt) are not available for your platform)
|
||||
|
||||
#### Add as a Dependency
|
||||
|
|
@ -34,31 +35,36 @@ const exe = b.addExecutable(.{...});
|
|||
exe.root_module.addImport("temporalz", temporalz.module("temporalz"));
|
||||
```
|
||||
|
||||
## Checklist
|
||||
|
||||
| Namespace | Status |
|
||||
| -------------- | ------ |
|
||||
| Instant | ✅ |
|
||||
| Duration | ✅ |
|
||||
| PlainDate | ✅ |
|
||||
| PlainTime | ✅ |
|
||||
| PlainDateTime | ✅ |
|
||||
| PlainYearMonth | ✅ |
|
||||
| PlainMonthDay | ✅ |
|
||||
| ZonedDateTime | ✅ |
|
||||
## Checklist ([Test262](https://github.com/tc39/test262/tree/main/test/built-ins/Temporal))
|
||||
|
||||
| Namespace | Test262 (todo) |
|
||||
| --- | --- |
|
||||
| Instant | 0/0 |
|
||||
| Duration | 0/0 |
|
||||
| PlainDate | 0/0 |
|
||||
| PlainTime | 0/0 |
|
||||
| PlainDateTime | 0/0 |
|
||||
| PlainYearMonth | 0/0 |
|
||||
| PlainMonthDay | 0/0 |
|
||||
| ZonedDateTime | 0/0 |
|
||||
|
||||
## Prebuilt
|
||||
|
||||
Prebuilt libraries are included for the following platforms:
|
||||
|
||||
- `x86_64-macos`, `aarch64-macos`
|
||||
- `x86_64-linux-gnu`, `aarch64-linux-gnu`, `x86-linux-gnu`, `arm-linux-gnueabihf`
|
||||
- `loongarch64-linux-gnu`, `powerpc64le-linux-gnu`, `riscv64-linux-gnu`, `s390x-linux-gnu`
|
||||
- `x86_64-windows-gnu`, `aarch64-windows-gnu`, `x86-windows-gnu`
|
||||
- `x86_64-freebsd`, `x86_64-netbsd`
|
||||
- `wasm32-freestanding`, `wasm32-wasi`
|
||||
- `x86_64-linux-musl`, `aarch64-linux-musl`
|
||||
- `aarch64-linux-android`, `aarch64-ios`
|
||||
- `x86_64-macos`
|
||||
- `aarch64-macos`
|
||||
- `x86_64-linux-gnu`
|
||||
- `aarch64-linux-gnu`
|
||||
- `x86_64-windows-gnu`
|
||||
- `aarch64-windows-gnu`
|
||||
- `wasm32-freestanding`
|
||||
- `wasm32-wasi`
|
||||
- `x86_64-linux-musl`
|
||||
- `aarch64-linux-musl`
|
||||
- `aarch64-linux-android`
|
||||
- `aarch64-ios`
|
||||
|
||||
For other platforms, the library will build from source; you need the Rust toolchain installed.
|
||||
|
||||
|
|
@ -75,12 +81,6 @@ cd temporalz
|
|||
|
||||
```bash
|
||||
zig build run
|
||||
|
||||
# Node.js
|
||||
zig build run -Dtarget=wasm32-freestanding
|
||||
|
||||
# wasmtime
|
||||
zig build run -Dtarget=wasm32-wasi
|
||||
```
|
||||
|
||||
#### Run Tests
|
||||
|
|
@ -88,3 +88,8 @@ zig build run -Dtarget=wasm32-wasi
|
|||
```bash
|
||||
zig build test
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
|
|
|
|||
298
SPEC.md
Normal file
298
SPEC.md
Normal file
|
|
@ -0,0 +1,298 @@
|
|||
Temporal.Duration
|
||||
Temporal.Instant
|
||||
Temporal.Now
|
||||
Temporal.PlainDate
|
||||
Temporal.PlainDateTime
|
||||
Temporal.PlainMonthDay
|
||||
Temporal.PlainTime
|
||||
Temporal.PlainYearMonth
|
||||
Temporal.ZonedDateTime
|
||||
|
||||
Temporal.Duration
|
||||
Constructor
|
||||
Temporal.Duration()
|
||||
Static methods
|
||||
compare()
|
||||
from()
|
||||
Instance methods
|
||||
abs()
|
||||
add()
|
||||
negated()
|
||||
round()
|
||||
subtract()
|
||||
toJSON()
|
||||
toLocaleString()
|
||||
toString()
|
||||
total()
|
||||
valueOf()
|
||||
with()
|
||||
Instance properties
|
||||
blank
|
||||
days
|
||||
hours
|
||||
microseconds
|
||||
milliseconds
|
||||
minutes
|
||||
months
|
||||
nanoseconds
|
||||
seconds
|
||||
sign
|
||||
weeks
|
||||
years
|
||||
|
||||
Temporal.Instant
|
||||
Constructor
|
||||
Temporal.Instant()
|
||||
Experimental
|
||||
Static methods
|
||||
compare()
|
||||
from()
|
||||
fromEpochMilliseconds()
|
||||
fromEpochNanoseconds()
|
||||
Instance methods
|
||||
add()
|
||||
equals()
|
||||
round()
|
||||
since()
|
||||
subtract()
|
||||
toJSON()
|
||||
toLocaleString()
|
||||
toString()
|
||||
toZonedDateTimeISO()
|
||||
until()
|
||||
valueOf()
|
||||
Instance properties
|
||||
epochMilliseconds
|
||||
epochNanoseconds
|
||||
|
||||
Temporal.Now
|
||||
Static methods
|
||||
instant()
|
||||
plainDateISO()
|
||||
plainDateTimeISO()
|
||||
plainTimeISO()
|
||||
timeZoneId()
|
||||
zonedDateTimeISO()
|
||||
|
||||
Temporal.PlainDate
|
||||
Constructor
|
||||
Temporal.PlainDate()
|
||||
Experimental
|
||||
Static methods
|
||||
compare()
|
||||
from()
|
||||
Instance methods
|
||||
add()
|
||||
equals()
|
||||
since()
|
||||
subtract()
|
||||
toJSON()
|
||||
toLocaleString()
|
||||
toPlainDateTime()
|
||||
toPlainMonthDay()
|
||||
toPlainYearMonth()
|
||||
toString()
|
||||
toZonedDateTime()
|
||||
until()
|
||||
valueOf()
|
||||
with()
|
||||
withCalendar()
|
||||
Instance properties
|
||||
calendarId
|
||||
day
|
||||
dayOfWeek
|
||||
dayOfYear
|
||||
daysInMonth
|
||||
daysInWeek
|
||||
daysInYear
|
||||
era
|
||||
eraYear
|
||||
inLeapYear
|
||||
month
|
||||
monthCode
|
||||
monthsInYear
|
||||
weekOfYear
|
||||
year
|
||||
yearOfWeek
|
||||
|
||||
Temporal.PlainDateTime
|
||||
Constructor
|
||||
Temporal.PlainDateTime()
|
||||
Experimental
|
||||
Static methods
|
||||
compare()
|
||||
from()
|
||||
Instance methods
|
||||
add()
|
||||
equals()
|
||||
round()
|
||||
since()
|
||||
subtract()
|
||||
toJSON()
|
||||
toLocaleString()
|
||||
toPlainDate()
|
||||
toPlainTime()
|
||||
toString()
|
||||
toZonedDateTime()
|
||||
until()
|
||||
valueOf()
|
||||
with()
|
||||
withCalendar()
|
||||
withPlainTime()
|
||||
Instance properties
|
||||
calendarId
|
||||
day
|
||||
dayOfWeek
|
||||
dayOfYear
|
||||
daysInMonth
|
||||
daysInWeek
|
||||
daysInYear
|
||||
era
|
||||
eraYear
|
||||
hour
|
||||
inLeapYear
|
||||
microsecond
|
||||
millisecond
|
||||
minute
|
||||
month
|
||||
monthCode
|
||||
monthsInYear
|
||||
nanosecond
|
||||
second
|
||||
weekOfYear
|
||||
year
|
||||
yearOfWeek
|
||||
|
||||
Temporal.PlainMonthDay
|
||||
Constructor
|
||||
Temporal.PlainMonthDay()
|
||||
Experimental
|
||||
Static methods
|
||||
from()
|
||||
Instance methods
|
||||
equals()
|
||||
toJSON()
|
||||
toLocaleString()
|
||||
toPlainDate()
|
||||
toString()
|
||||
valueOf()
|
||||
with()
|
||||
Instance properties
|
||||
calendarId
|
||||
day
|
||||
monthCode
|
||||
|
||||
Temporal.PlainTime
|
||||
Constructor
|
||||
Temporal.PlainTime()
|
||||
Static methods
|
||||
compare()
|
||||
from()
|
||||
Instance methods
|
||||
add()
|
||||
equals()
|
||||
round()
|
||||
since()
|
||||
subtract()
|
||||
toJSON()
|
||||
toLocaleString()
|
||||
toString()
|
||||
until()
|
||||
valueOf()
|
||||
with()
|
||||
Instance properties
|
||||
hour
|
||||
microsecond
|
||||
millisecond
|
||||
minute
|
||||
nanosecond
|
||||
second
|
||||
|
||||
Temporal.PlainYearMonth
|
||||
Constructor
|
||||
Temporal.PlainYearMonth()
|
||||
Experimental
|
||||
Static methods
|
||||
compare()
|
||||
from()
|
||||
Instance methods
|
||||
add()
|
||||
equals()
|
||||
since()
|
||||
subtract()
|
||||
toJSON()
|
||||
toLocaleString()
|
||||
toPlainDate()
|
||||
toString()
|
||||
until()
|
||||
valueOf()
|
||||
with()
|
||||
Instance properties
|
||||
calendarId
|
||||
daysInMonth
|
||||
daysInYear
|
||||
era
|
||||
eraYear
|
||||
inLeapYear
|
||||
month
|
||||
monthCode
|
||||
monthsInYear
|
||||
year
|
||||
|
||||
Temporal.ZonedDateTime
|
||||
Constructor
|
||||
Temporal.ZonedDateTime()
|
||||
Experimental
|
||||
Static methods
|
||||
compare()
|
||||
from()
|
||||
Instance methods
|
||||
add()
|
||||
equals()
|
||||
getTimeZoneTransition()
|
||||
round()
|
||||
since()
|
||||
startOfDay()
|
||||
subtract()
|
||||
toInstant()
|
||||
toJSON()
|
||||
toLocaleString()
|
||||
toPlainDate()
|
||||
toPlainDateTime()
|
||||
toPlainTime()
|
||||
toString()
|
||||
until()
|
||||
valueOf()
|
||||
with()
|
||||
withCalendar()
|
||||
withPlainTime()
|
||||
withTimeZone()
|
||||
Instance properties
|
||||
calendarId
|
||||
day
|
||||
dayOfWeek
|
||||
dayOfYear
|
||||
daysInMonth
|
||||
daysInWeek
|
||||
daysInYear
|
||||
epochMilliseconds
|
||||
epochNanoseconds
|
||||
era
|
||||
eraYear
|
||||
hour
|
||||
hoursInDay
|
||||
inLeapYear
|
||||
microsecond
|
||||
millisecond
|
||||
minute
|
||||
month
|
||||
monthCode
|
||||
monthsInYear
|
||||
nanosecond
|
||||
offset
|
||||
offsetNanoseconds
|
||||
second
|
||||
timeZoneId
|
||||
weekOfYear
|
||||
year
|
||||
yearOfWeek
|
||||
57
build.zig
57
build.zig
|
|
@ -3,38 +3,58 @@ const std = @import("std");
|
|||
pub fn build(b: *std.Build) !void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const is_freestanding = target.result.os.tag == .freestanding;
|
||||
const force_build_rust = b.option(bool, "build-rust", "Always build Rust library from source") orelse false;
|
||||
|
||||
// --- Rust C ABI & Pre-built via temporal-rs subpackage --- //
|
||||
const build_rust = b.option(bool, "build-rust", "Build Rust library from source") orelse false;
|
||||
const libtemporal = b.dependency("libtemporal", .{
|
||||
const temporal = b.dependency("temporal", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.@"build-rust" = build_rust,
|
||||
.@"build-rust" = force_build_rust,
|
||||
});
|
||||
|
||||
// --- Module: temporalz --- //
|
||||
// --- Zig Module: temporalz --- //
|
||||
const mod = b.addModule("temporalz", .{
|
||||
.root_source_file = b.path("src/root.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
mod.addImport("libtemporal", libtemporal.module("libtemporal"));
|
||||
mod.addImport("temporal_rs", temporal.module("temporal_rs"));
|
||||
|
||||
// --- Step: run --- //
|
||||
// --- Zig Executable: temporalz --- //
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "temporalz",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = if (is_freestanding)
|
||||
b.path("example/src/wasm.zig")
|
||||
else
|
||||
b.path("example/src/main.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.imports = &.{
|
||||
.{ .name = "temporalz", .module = mod },
|
||||
},
|
||||
}),
|
||||
});
|
||||
exe.root_module.link_libc = !is_freestanding;
|
||||
exe.rdynamic = is_freestanding;
|
||||
b.installArtifact(exe);
|
||||
|
||||
// --- Steps: Run --- //
|
||||
{
|
||||
const run_step = b.step("run", "Run the test project");
|
||||
const run_step = b.step("run", "Run the example project");
|
||||
const run_cmd = b.addSystemCommand(&.{
|
||||
b.graph.zig_exe,
|
||||
"build",
|
||||
"run",
|
||||
b.fmt("-Dtarget={s}", .{try target.result.zigTriple(b.allocator)}),
|
||||
});
|
||||
run_cmd.setCwd(b.path("test"));
|
||||
run_cmd.addPassthruArgs();
|
||||
run_cmd.setCwd(b.path("example"));
|
||||
if (b.args) |args| run_cmd.addArgs(args);
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
}
|
||||
|
||||
// --- Step: docs --- //
|
||||
// --- Steps: Docs --- //
|
||||
{
|
||||
const docs_step = b.step("docs", "Build the temporalz docs");
|
||||
const docs_obj = b.addObject(.{ .name = "temporalz", .root_module = mod });
|
||||
|
|
@ -47,7 +67,7 @@ pub fn build(b: *std.Build) !void {
|
|||
}).step);
|
||||
}
|
||||
|
||||
// --- Step: test --- //
|
||||
// --- Steps: Test --- //
|
||||
{
|
||||
const test_step = b.step("test", "Run tests");
|
||||
const mod_tests = b.addTest(.{
|
||||
|
|
@ -57,7 +77,20 @@ pub fn build(b: *std.Build) !void {
|
|||
.mode = .simple,
|
||||
},
|
||||
});
|
||||
mod_tests.root_module.link_libc = target.result.os.tag != .freestanding;
|
||||
mod_tests.root_module.link_libc = !is_freestanding;
|
||||
test_step.dependOn(&b.addRunArtifact(mod_tests).step);
|
||||
if (!is_freestanding) {
|
||||
const exe_tests = b.addTest(.{ .root_module = exe.root_module });
|
||||
test_step.dependOn(&b.addRunArtifact(exe_tests).step);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Steps: test-262 --- //
|
||||
{
|
||||
const test262_step = b.step("test262", "Run test-262 tests");
|
||||
const run_cmd = b.addSystemCommand(&.{ "node", "test/test262/runner.mjs" });
|
||||
if (b.args) |args| run_cmd.addArgs(args);
|
||||
run_cmd.step.dependOn(b.getInstallStep());
|
||||
test262_step.dependOn(&run_cmd.step);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
.{
|
||||
.name = .temporalz,
|
||||
.version = "0.2.4",
|
||||
.version = "0.2.0",
|
||||
.fingerprint = 0xd8d79d59acc4faae,
|
||||
.minimum_zig_version = "0.17.0-dev.1398+cb5635714",
|
||||
.minimum_zig_version = "0.17.0-dev.387+31f157d80",
|
||||
.dependencies = .{
|
||||
.libtemporal = .{
|
||||
.path = "lib",
|
||||
.temporal = .{
|
||||
.path = "pkg/temporal",
|
||||
},
|
||||
},
|
||||
.paths = .{
|
||||
|
|
@ -14,6 +14,6 @@
|
|||
"README.md",
|
||||
"LICENCE",
|
||||
"src",
|
||||
"lib",
|
||||
"pkg",
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,18 +12,15 @@ pub fn build(b: *std.Build) void {
|
|||
const exe = b.addExecutable(.{
|
||||
.name = "temporalz",
|
||||
.root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.root_source_file = b.path(if (is_freestanding) "src/wasm.zig" else "src/main.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.link_libc = !is_freestanding,
|
||||
.imports = &.{},
|
||||
}),
|
||||
});
|
||||
exe.root_module.addImport("temporalz", temporalz.module("temporalz"));
|
||||
exe.rdynamic = is_freestanding;
|
||||
if (is_freestanding) exe.entry = .disabled;
|
||||
b.installArtifact(exe);
|
||||
b.enable_wasmtime = true; // This doesn't work since Zig 0.17.0 release
|
||||
b.enable_wasmtime = true;
|
||||
|
||||
const run_step = b.step("run", "Run the app");
|
||||
switch (target.result.os.tag) {
|
||||
|
|
@ -32,16 +29,10 @@ pub fn build(b: *std.Build) void {
|
|||
run_cmd.step.dependOn(b.getInstallStep());
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
},
|
||||
.wasi => {
|
||||
const run_cmd = b.addSystemCommand(&.{"wasmtime"});
|
||||
run_cmd.addFileArg(exe.getEmittedBin());
|
||||
run_cmd.step.dependOn(b.getInstallStep());
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
},
|
||||
else => {
|
||||
const run_cmd = b.addRunArtifact(exe);
|
||||
run_cmd.step.dependOn(b.getInstallStep());
|
||||
run_cmd.addPassthruArgs();
|
||||
if (b.args) |args| run_cmd.addArgs(args);
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
},
|
||||
}
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
.{
|
||||
.name = .temporalz_example,
|
||||
.version = "0.0.0",
|
||||
.version = "0.1.2",
|
||||
.fingerprint = 0x686c9dfc777f9593,
|
||||
.minimum_zig_version = "0.17.0-dev.387+31f157d80",
|
||||
.dependencies = .{
|
||||
.temporalz = .{
|
||||
.path = "../",
|
||||
17
example/src/main.mjs
Normal file
17
example/src/main.mjs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { readFile } from 'fs/promises';
|
||||
|
||||
let memory = null;
|
||||
|
||||
const buffer = await readFile('zig-out/bin/temporalz.wasm');
|
||||
const temporalz = await WebAssembly.instantiate(buffer, {
|
||||
env: {
|
||||
console(ptr, len) {
|
||||
const bytes = new Uint8Array(memory.buffer, ptr, len);
|
||||
const message = new TextDecoder().decode(bytes);
|
||||
console.log(message);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
memory = temporalz.instance.exports.memory;
|
||||
temporalz.instance.exports._start();
|
||||
9
example/src/main.zig
Normal file
9
example/src/main.zig
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
const std = @import("std");
|
||||
const program = @import("root.zig");
|
||||
|
||||
pub fn main(init: std.process.Init) !void {
|
||||
const allocator = init.arena.allocator();
|
||||
const io = init.io;
|
||||
|
||||
try program.run(allocator, io);
|
||||
}
|
||||
|
|
@ -53,10 +53,10 @@ pub fn run(allocator: std.mem.Allocator, io_optional: ?std.Io) !void {
|
|||
if (io_optional) |io| {
|
||||
const now_instant = try Temporal.Now.instant(io);
|
||||
defer now_instant.deinit();
|
||||
const now_date = try Temporal.Now.plainDateISO(allocator, io, null);
|
||||
const now_date = try Temporal.Now.plainDateISO(io);
|
||||
defer now_date.deinit();
|
||||
const now_datetime = try Temporal.Now.plainDateTimeISO(allocator, io, null);
|
||||
const now_time = try Temporal.Now.plainTimeISO(allocator, io, null);
|
||||
const now_datetime = try Temporal.Now.plainDateTimeISO(io);
|
||||
const now_time = try Temporal.Now.plainTimeISO(io);
|
||||
std.log.info(
|
||||
\\Now
|
||||
\\ - instant: {s}
|
||||
|
|
@ -186,8 +186,6 @@ pub fn run(allocator: std.mem.Allocator, io_optional: ?std.Io) !void {
|
|||
try zdt.toString(allocator, .{}),
|
||||
});
|
||||
|
||||
try runTimeZoneExamples(allocator, io_optional, null);
|
||||
|
||||
// ----
|
||||
// More complex Temporal API examples
|
||||
// ----
|
||||
|
|
@ -524,22 +522,18 @@ pub fn run(allocator: std.mem.Allocator, io_optional: ?std.Io) !void {
|
|||
try instant_zdt.toString(allocator, .{}),
|
||||
});
|
||||
|
||||
if (io_optional) |io| {
|
||||
const now_zdt = try Temporal.Now.zonedDateTimeISO(allocator, io, null);
|
||||
defer now_zdt.deinit();
|
||||
const now_tz_id = try Temporal.Now.timeZoneId(allocator, io);
|
||||
defer allocator.free(now_tz_id);
|
||||
std.log.info(
|
||||
\\Now Coverage
|
||||
\\ - timeZoneId(): {s}
|
||||
\\ - zonedDateTimeISO(): {s}
|
||||
\\
|
||||
\\
|
||||
, .{
|
||||
now_tz_id,
|
||||
try now_zdt.toString(allocator, .{}),
|
||||
});
|
||||
}
|
||||
const now_zdt = try Temporal.Now.zonedDateTimeISO();
|
||||
defer now_zdt.deinit();
|
||||
std.log.info(
|
||||
\\Now Coverage
|
||||
\\ - timeZoneId(): {s}
|
||||
\\ - zonedDateTimeISO(): {s}
|
||||
\\
|
||||
\\
|
||||
, .{
|
||||
Temporal.Now.timeZoneId(),
|
||||
try now_zdt.toString(allocator, .{}),
|
||||
});
|
||||
|
||||
const date_cal = try Temporal.PlainDate.calInit(2024, 2, 2, "iso8601");
|
||||
const date_from = try Temporal.PlainDate.from("2024-02-02");
|
||||
|
|
@ -816,98 +810,17 @@ pub fn run(allocator: std.mem.Allocator, io_optional: ?std.Io) !void {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn runTimeZoneExamples(
|
||||
allocator: std.mem.Allocator,
|
||||
io_optional: ?std.Io,
|
||||
now_epoch_ms: ?i64,
|
||||
) !void {
|
||||
const epoch_ns: i128 = if (now_epoch_ms) |ms| @as(i128, ms) * 1_000_000 else 1_706_881_530_123_456_789;
|
||||
|
||||
const utc_tz = try Temporal.ZonedDateTime.TimeZone.init("UTC");
|
||||
const ny_tz = try Temporal.ZonedDateTime.TimeZone.init("America/New_York");
|
||||
const dhaka_tz = try Temporal.ZonedDateTime.TimeZone.init("Asia/Dhaka");
|
||||
|
||||
const zdt_utc = try Temporal.ZonedDateTime.fromEpochNanoseconds(epoch_ns, utc_tz);
|
||||
defer zdt_utc.deinit();
|
||||
const zdt_ny = try zdt_utc.withTimeZone(ny_tz);
|
||||
defer zdt_ny.deinit();
|
||||
const zdt_dhaka = try zdt_utc.withTimeZone(dhaka_tz);
|
||||
defer zdt_dhaka.deinit();
|
||||
|
||||
const utc_id = try zdt_utc.timeZoneId(allocator);
|
||||
defer allocator.free(utc_id);
|
||||
const ny_id = try zdt_ny.timeZoneId(allocator);
|
||||
defer allocator.free(ny_id);
|
||||
const dhaka_id = try zdt_dhaka.timeZoneId(allocator);
|
||||
defer allocator.free(dhaka_id);
|
||||
|
||||
std.log.info(
|
||||
\\TimeZone
|
||||
\\ - same instant in UTC ({s}): {s}
|
||||
\\ - same instant in New York ({s}): {s}
|
||||
\\ - same instant in Dhaka ({s}): {s}
|
||||
\\ - UTC offset: {s}
|
||||
\\ - New York offset: {s}
|
||||
\\ - Dhaka offset: {s}
|
||||
\\
|
||||
\\
|
||||
, .{
|
||||
utc_id,
|
||||
try zdt_utc.toString(allocator, .{}),
|
||||
ny_id,
|
||||
try zdt_ny.toString(allocator, .{}),
|
||||
dhaka_id,
|
||||
try zdt_dhaka.toString(allocator, .{}),
|
||||
try zdt_utc.offset(allocator),
|
||||
try zdt_ny.offset(allocator),
|
||||
try zdt_dhaka.offset(allocator),
|
||||
});
|
||||
|
||||
if (io_optional) |io| {
|
||||
const system_tz_id = try Temporal.Now.timeZoneId(allocator, io);
|
||||
defer allocator.free(system_tz_id);
|
||||
|
||||
const now_zdt = try Temporal.Now.zonedDateTimeISO(allocator, io, null);
|
||||
defer now_zdt.deinit();
|
||||
const now_zdt_utc = try Temporal.Now.zonedDateTimeISO(allocator, io, "UTC");
|
||||
defer now_zdt_utc.deinit();
|
||||
const now_date = try Temporal.Now.plainDateISO(allocator, io, null);
|
||||
defer now_date.deinit();
|
||||
|
||||
std.log.info(
|
||||
\\TimeZone (system)
|
||||
\\ - system timeZoneId(): {s}
|
||||
\\ - Now.zonedDateTimeISO(): {s}
|
||||
\\ - Now.zonedDateTimeISO("UTC"): {s}
|
||||
\\ - Now.plainDateISO(): {s}
|
||||
\\
|
||||
\\
|
||||
, .{
|
||||
system_tz_id,
|
||||
try now_zdt.toString(allocator, .{}),
|
||||
try now_zdt_utc.toString(allocator, .{}),
|
||||
try now_date.toString(allocator, .{}),
|
||||
});
|
||||
} else if (now_epoch_ms) |ms| {
|
||||
const inst = try Temporal.Instant.fromEpochMilliseconds(ms);
|
||||
defer inst.deinit();
|
||||
|
||||
const inst_dhaka_tz = try Temporal.Instant.TimeZone.init("Asia/Dhaka");
|
||||
const inst_utc_tz = try Temporal.Instant.TimeZone.init("UTC");
|
||||
const host_zdt = try inst.toZonedDateTimeISO(inst_dhaka_tz);
|
||||
defer host_zdt.deinit();
|
||||
const host_zdt_utc = try inst.toZonedDateTimeISO(inst_utc_tz);
|
||||
defer host_zdt_utc.deinit();
|
||||
|
||||
std.log.info(
|
||||
\\TimeZone (host epoch)
|
||||
\\ - Instant.toZonedDateTimeISO("Asia/Dhaka"): {s}
|
||||
\\ - Instant.toZonedDateTimeISO("UTC"): {s}
|
||||
\\
|
||||
\\
|
||||
, .{
|
||||
try host_zdt.toString(allocator, .{}),
|
||||
try host_zdt_utc.toString(allocator, .{}),
|
||||
});
|
||||
extern fn consoleLog(ptr: [*]u8, len: u32) void;
|
||||
pub fn logFn(comptime message_level: std.log.Level, comptime scope: @TypeOf(.enum_literal), comptime format: []const u8, args: anytype) void {
|
||||
if (builtin.os.tag == .freestanding) {
|
||||
const prefix = if (scope == .default) "" else "(" ++ @tagName(scope) ++ ") ";
|
||||
const formatted = std.fmt.allocPrint(std.heap.wasm_allocator, prefix ++ format, args) catch return;
|
||||
consoleLog(formatted.ptr, formatted.len);
|
||||
}
|
||||
|
||||
std.log.defaultLog(message_level, scope, format, args);
|
||||
}
|
||||
|
||||
pub const std_options: std.Options = .{
|
||||
.logFn = logFn,
|
||||
};
|
||||
842
example/src/wasm.zig
Normal file
842
example/src/wasm.zig
Normal file
|
|
@ -0,0 +1,842 @@
|
|||
const std = @import("std");
|
||||
const program = @import("root.zig");
|
||||
const Temporal = @import("temporalz");
|
||||
|
||||
export fn _start() void {
|
||||
const allocator = std.heap.page_allocator;
|
||||
program.run(allocator, null) catch {};
|
||||
}
|
||||
|
||||
const wasm_allocator = std.heap.wasm_allocator;
|
||||
const PolyfillError = error{InvalidHandle};
|
||||
|
||||
var instants_init = false;
|
||||
var durations_init = false;
|
||||
var instants: std.ArrayList(?Temporal.Instant) = .empty;
|
||||
var durations: std.ArrayList(?Temporal.Duration) = .empty;
|
||||
var plain_dates_init = false;
|
||||
var plain_dates: std.ArrayList(?Temporal.PlainDate) = .empty;
|
||||
|
||||
var last_error: ?[]u8 = null;
|
||||
|
||||
fn ensureInstants() void {
|
||||
if (!instants_init) {
|
||||
instants = .empty;
|
||||
instants_init = true;
|
||||
}
|
||||
}
|
||||
|
||||
fn ensureDurations() void {
|
||||
if (!durations_init) {
|
||||
durations = .empty;
|
||||
durations_init = true;
|
||||
}
|
||||
}
|
||||
|
||||
fn ensurePlainDates() void {
|
||||
if (!plain_dates_init) {
|
||||
plain_dates = .empty;
|
||||
plain_dates_init = true;
|
||||
}
|
||||
}
|
||||
|
||||
fn addInstant(inst: Temporal.Instant) u32 {
|
||||
ensureInstants();
|
||||
instants.append(wasm_allocator, inst) catch return 0;
|
||||
return @intCast(instants.items.len);
|
||||
}
|
||||
|
||||
fn getInstant(handle: u32) !Temporal.Instant {
|
||||
ensureInstants();
|
||||
if (handle == 0 or handle > instants.items.len) return PolyfillError.InvalidHandle;
|
||||
return instants.items[handle - 1] orelse PolyfillError.InvalidHandle;
|
||||
}
|
||||
|
||||
fn removeInstant(handle: u32) void {
|
||||
if (!instants_init or handle == 0 or handle > instants.items.len) return;
|
||||
if (instants.items[handle - 1]) |inst| {
|
||||
inst.deinit();
|
||||
instants.items[handle - 1] = null;
|
||||
}
|
||||
}
|
||||
|
||||
fn addDuration(dur: Temporal.Duration) u32 {
|
||||
ensureDurations();
|
||||
durations.append(wasm_allocator, dur) catch return 0;
|
||||
return @intCast(durations.items.len);
|
||||
}
|
||||
|
||||
fn getDuration(handle: u32) !Temporal.Duration {
|
||||
ensureDurations();
|
||||
if (handle == 0 or handle > durations.items.len) return PolyfillError.InvalidHandle;
|
||||
return durations.items[handle - 1] orelse PolyfillError.InvalidHandle;
|
||||
}
|
||||
|
||||
fn removeDuration(handle: u32) void {
|
||||
if (!durations_init or handle == 0 or handle > durations.items.len) return;
|
||||
if (durations.items[handle - 1]) |dur| {
|
||||
dur.deinit();
|
||||
durations.items[handle - 1] = null;
|
||||
}
|
||||
}
|
||||
|
||||
fn addPlainDate(date: Temporal.PlainDate) u32 {
|
||||
ensurePlainDates();
|
||||
plain_dates.append(wasm_allocator, date) catch return 0;
|
||||
return @intCast(plain_dates.items.len);
|
||||
}
|
||||
|
||||
fn getPlainDate(handle: u32) !Temporal.PlainDate {
|
||||
ensurePlainDates();
|
||||
if (handle == 0 or handle > plain_dates.items.len) return PolyfillError.InvalidHandle;
|
||||
return plain_dates.items[handle - 1] orelse PolyfillError.InvalidHandle;
|
||||
}
|
||||
|
||||
fn removePlainDate(handle: u32) void {
|
||||
if (!plain_dates_init or handle == 0 or handle > plain_dates.items.len) return;
|
||||
if (plain_dates.items[handle - 1]) |date| {
|
||||
date.deinit();
|
||||
plain_dates.items[handle - 1] = null;
|
||||
}
|
||||
}
|
||||
|
||||
fn clearLastError() void {
|
||||
if (last_error) |msg| {
|
||||
wasm_allocator.free(msg);
|
||||
last_error = null;
|
||||
}
|
||||
}
|
||||
|
||||
fn setLastError(err: anyerror) void {
|
||||
clearLastError();
|
||||
const msg = std.fmt.allocPrint(wasm_allocator, "{s}", .{@errorName(err)}) catch return;
|
||||
last_error = msg;
|
||||
}
|
||||
|
||||
fn setLastErrorMessage(msg: []const u8) void {
|
||||
clearLastError();
|
||||
const owned = wasm_allocator.alloc(u8, msg.len) catch return;
|
||||
std.mem.copyForwards(u8, owned, msg);
|
||||
last_error = owned;
|
||||
}
|
||||
|
||||
fn packPtrLen(ptr: [*]u8, len: usize) u64 {
|
||||
const ptr_u32: u32 = @intCast(@intFromPtr(ptr));
|
||||
const len_u32: u32 = @intCast(len);
|
||||
return (@as(u64, ptr_u32) << 32) | @as(u64, len_u32);
|
||||
}
|
||||
|
||||
fn unpackI128Hi(value: i128) i64 {
|
||||
const bits: u128 = @bitCast(value);
|
||||
const hi_bits: u64 = @intCast(bits >> 64);
|
||||
return @bitCast(hi_bits);
|
||||
}
|
||||
|
||||
fn unpackI128Lo(value: i128) u64 {
|
||||
const bits: u128 = @bitCast(value);
|
||||
return @intCast(bits & 0xFFFFFFFFFFFFFFFF);
|
||||
}
|
||||
|
||||
fn joinI128(hi: i64, lo: u64) i128 {
|
||||
const hi_bits: u64 = @bitCast(hi);
|
||||
const value: u128 = (@as(u128, hi_bits) << 64) | @as(u128, lo);
|
||||
return @bitCast(value);
|
||||
}
|
||||
|
||||
fn unitFromCode(code: u8) ?Temporal.Duration.Unit {
|
||||
return switch (code) {
|
||||
1 => .nanosecond,
|
||||
2 => .microsecond,
|
||||
3 => .millisecond,
|
||||
4 => .second,
|
||||
5 => .minute,
|
||||
6 => .hour,
|
||||
7 => .day,
|
||||
8 => .week,
|
||||
9 => .month,
|
||||
10 => .year,
|
||||
11 => .auto,
|
||||
else => null,
|
||||
};
|
||||
}
|
||||
|
||||
fn roundingModeFromCode(code: u8) ?Temporal.Duration.RoundingMode {
|
||||
return switch (code) {
|
||||
1 => .ceil,
|
||||
2 => .floor,
|
||||
3 => .expand,
|
||||
4 => .trunc,
|
||||
5 => .half_ceil,
|
||||
6 => .half_floor,
|
||||
7 => .half_expand,
|
||||
8 => .half_trunc,
|
||||
9 => .half_even,
|
||||
else => null,
|
||||
};
|
||||
}
|
||||
|
||||
export fn temporalz_last_error_ptr() usize {
|
||||
return if (last_error) |msg| @intFromPtr(msg.ptr) else 0;
|
||||
}
|
||||
|
||||
export fn temporalz_last_error_len() usize {
|
||||
return if (last_error) |msg| msg.len else 0;
|
||||
}
|
||||
|
||||
export fn temporalz_last_error_clear() void {
|
||||
clearLastError();
|
||||
}
|
||||
|
||||
export fn temporalz_alloc(len: usize) usize {
|
||||
clearLastError();
|
||||
const buf = wasm_allocator.alloc(u8, len) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return @intFromPtr(buf.ptr);
|
||||
}
|
||||
|
||||
export fn temporalz_free(ptr: usize, len: usize) void {
|
||||
if (ptr == 0 or len == 0) return;
|
||||
const slice = @as([*]u8, @ptrFromInt(ptr))[0..len];
|
||||
wasm_allocator.free(slice);
|
||||
}
|
||||
|
||||
export fn temporalz_string_free(ptr: usize, len: usize) void {
|
||||
temporalz_free(ptr, len);
|
||||
}
|
||||
|
||||
export fn temporalz_instant_from_utf8(ptr: [*]const u8, len: usize) u32 {
|
||||
clearLastError();
|
||||
const text = ptr[0..len];
|
||||
const inst = Temporal.Instant.from(text) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return addInstant(inst);
|
||||
}
|
||||
|
||||
export fn temporalz_instant_from_epoch_milliseconds(epoch_ms: i64) u32 {
|
||||
clearLastError();
|
||||
const inst = Temporal.Instant.fromEpochMilliseconds(epoch_ms) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return addInstant(inst);
|
||||
}
|
||||
|
||||
export fn temporalz_instant_from_epoch_nanoseconds_parts(hi: i64, lo: u64) u32 {
|
||||
clearLastError();
|
||||
const epoch_ns = joinI128(hi, lo);
|
||||
const inst = Temporal.Instant.fromEpochNanoseconds(epoch_ns) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return addInstant(inst);
|
||||
}
|
||||
|
||||
export fn temporalz_instant_epoch_milliseconds(handle: u32) i64 {
|
||||
clearLastError();
|
||||
const inst = getInstant(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return inst.epochMilliseconds();
|
||||
}
|
||||
|
||||
export fn temporalz_instant_epoch_nanoseconds_hi(handle: u32) i64 {
|
||||
clearLastError();
|
||||
const inst = getInstant(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return unpackI128Hi(inst.epochNanoseconds());
|
||||
}
|
||||
|
||||
export fn temporalz_instant_epoch_nanoseconds_lo(handle: u32) u64 {
|
||||
clearLastError();
|
||||
const inst = getInstant(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return unpackI128Lo(inst.epochNanoseconds());
|
||||
}
|
||||
|
||||
export fn temporalz_instant_to_string(handle: u32) u64 {
|
||||
clearLastError();
|
||||
const inst = getInstant(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const text = inst.toString(wasm_allocator, .{}) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return packPtrLen(text.ptr, text.len);
|
||||
}
|
||||
|
||||
export fn temporalz_instant_add(handle: u32, duration_handle: u32) u32 {
|
||||
clearLastError();
|
||||
const inst = getInstant(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
var dur = getDuration(duration_handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const res = inst.add(&dur) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return addInstant(res);
|
||||
}
|
||||
|
||||
export fn temporalz_instant_subtract(handle: u32, duration_handle: u32) u32 {
|
||||
clearLastError();
|
||||
const inst = getInstant(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
var dur = getDuration(duration_handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const res = inst.subtract(&dur) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return addInstant(res);
|
||||
}
|
||||
|
||||
export fn temporalz_instant_compare(handle_a: u32, handle_b: u32) i32 {
|
||||
clearLastError();
|
||||
const a = getInstant(handle_a) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const b = getInstant(handle_b) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return @intCast(Temporal.Instant.compare(a, b));
|
||||
}
|
||||
|
||||
export fn temporalz_instant_equals(handle_a: u32, handle_b: u32) u8 {
|
||||
clearLastError();
|
||||
const a = getInstant(handle_a) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const b = getInstant(handle_b) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return if (Temporal.Instant.equals(a, b)) 1 else 0;
|
||||
}
|
||||
|
||||
export fn temporalz_instant_round(
|
||||
handle: u32,
|
||||
smallest_unit: u8,
|
||||
rounding_mode: u8,
|
||||
rounding_increment: u32,
|
||||
) u32 {
|
||||
clearLastError();
|
||||
const inst = getInstant(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
|
||||
var opts = Temporal.Instant.RoundingOptions{};
|
||||
if (smallest_unit != 255) {
|
||||
opts.smallest_unit = unitFromCode(smallest_unit) orelse {
|
||||
setLastErrorMessage("Invalid smallestUnit");
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
if (rounding_mode != 255) {
|
||||
opts.rounding_mode = roundingModeFromCode(rounding_mode) orelse {
|
||||
setLastErrorMessage("Invalid roundingMode");
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
if (rounding_increment != 0) {
|
||||
opts.rounding_increment = rounding_increment;
|
||||
}
|
||||
|
||||
const res = inst.round(opts) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return addInstant(res);
|
||||
}
|
||||
|
||||
export fn temporalz_instant_destroy(handle: u32) void {
|
||||
removeInstant(handle);
|
||||
}
|
||||
|
||||
export fn temporalz_duration_from_utf8(ptr: [*]const u8, len: usize) u32 {
|
||||
clearLastError();
|
||||
const text = ptr[0..len];
|
||||
const dur = Temporal.Duration.from(text) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return addDuration(dur);
|
||||
}
|
||||
|
||||
export fn temporalz_duration_from_parts(
|
||||
mask: u32,
|
||||
years: i64,
|
||||
months: i64,
|
||||
weeks: i64,
|
||||
days: i64,
|
||||
hours: i64,
|
||||
minutes: i64,
|
||||
seconds: i64,
|
||||
milliseconds: i64,
|
||||
microseconds: f64,
|
||||
nanoseconds: f64,
|
||||
) u32 {
|
||||
clearLastError();
|
||||
var partial = Temporal.Duration.PartialDuration{};
|
||||
if ((mask & 0x1) != 0) partial.years = years;
|
||||
if ((mask & 0x2) != 0) partial.months = months;
|
||||
if ((mask & 0x4) != 0) partial.weeks = weeks;
|
||||
if ((mask & 0x8) != 0) partial.days = days;
|
||||
if ((mask & 0x10) != 0) partial.hours = hours;
|
||||
if ((mask & 0x20) != 0) partial.minutes = minutes;
|
||||
if ((mask & 0x40) != 0) partial.seconds = seconds;
|
||||
if ((mask & 0x80) != 0) partial.milliseconds = milliseconds;
|
||||
if ((mask & 0x100) != 0) partial.microseconds = microseconds;
|
||||
if ((mask & 0x200) != 0) partial.nanoseconds = nanoseconds;
|
||||
|
||||
const dur = Temporal.Duration.from(partial) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return addDuration(dur);
|
||||
}
|
||||
|
||||
export fn temporalz_duration_init(
|
||||
years: i64,
|
||||
months: i64,
|
||||
weeks: i64,
|
||||
days: i64,
|
||||
hours: i64,
|
||||
minutes: i64,
|
||||
seconds: i64,
|
||||
milliseconds: i64,
|
||||
microseconds: f64,
|
||||
nanoseconds: f64,
|
||||
) u32 {
|
||||
clearLastError();
|
||||
const dur = Temporal.Duration.init(
|
||||
years,
|
||||
months,
|
||||
weeks,
|
||||
days,
|
||||
hours,
|
||||
minutes,
|
||||
seconds,
|
||||
milliseconds,
|
||||
microseconds,
|
||||
nanoseconds,
|
||||
) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return addDuration(dur);
|
||||
}
|
||||
|
||||
export fn temporalz_duration_to_string(handle: u32) u64 {
|
||||
clearLastError();
|
||||
const dur = getDuration(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const text = dur.toString(wasm_allocator, .{}) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return packPtrLen(text.ptr, text.len);
|
||||
}
|
||||
|
||||
export fn temporalz_duration_years(handle: u32) i64 {
|
||||
clearLastError();
|
||||
const dur = getDuration(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return dur.years();
|
||||
}
|
||||
|
||||
export fn temporalz_duration_months(handle: u32) i64 {
|
||||
clearLastError();
|
||||
const dur = getDuration(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return dur.months();
|
||||
}
|
||||
|
||||
export fn temporalz_duration_weeks(handle: u32) i64 {
|
||||
clearLastError();
|
||||
const dur = getDuration(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return dur.weeks();
|
||||
}
|
||||
|
||||
export fn temporalz_duration_days(handle: u32) i64 {
|
||||
clearLastError();
|
||||
const dur = getDuration(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return dur.days();
|
||||
}
|
||||
|
||||
export fn temporalz_duration_hours(handle: u32) i64 {
|
||||
clearLastError();
|
||||
const dur = getDuration(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return dur.hours();
|
||||
}
|
||||
|
||||
export fn temporalz_duration_minutes(handle: u32) i64 {
|
||||
clearLastError();
|
||||
const dur = getDuration(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return dur.minutes();
|
||||
}
|
||||
|
||||
export fn temporalz_duration_seconds(handle: u32) i64 {
|
||||
clearLastError();
|
||||
const dur = getDuration(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return dur.seconds();
|
||||
}
|
||||
|
||||
export fn temporalz_duration_milliseconds(handle: u32) i64 {
|
||||
clearLastError();
|
||||
const dur = getDuration(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return dur.milliseconds();
|
||||
}
|
||||
|
||||
export fn temporalz_duration_microseconds(handle: u32) f64 {
|
||||
clearLastError();
|
||||
const dur = getDuration(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return dur.microseconds();
|
||||
}
|
||||
|
||||
export fn temporalz_duration_nanoseconds(handle: u32) f64 {
|
||||
clearLastError();
|
||||
const dur = getDuration(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return dur.nanoseconds();
|
||||
}
|
||||
|
||||
export fn temporalz_duration_sign(handle: u32) i32 {
|
||||
clearLastError();
|
||||
const dur = getDuration(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return switch (dur.sign()) {
|
||||
.positive => 1,
|
||||
.zero => 0,
|
||||
.negative => -1,
|
||||
};
|
||||
}
|
||||
|
||||
export fn temporalz_duration_blank(handle: u32) u8 {
|
||||
clearLastError();
|
||||
const dur = getDuration(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return if (dur.blank()) 1 else 0;
|
||||
}
|
||||
|
||||
export fn temporalz_duration_abs(handle: u32) u32 {
|
||||
clearLastError();
|
||||
const dur = getDuration(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return addDuration(dur.abs());
|
||||
}
|
||||
|
||||
export fn temporalz_duration_negated(handle: u32) u32 {
|
||||
clearLastError();
|
||||
const dur = getDuration(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return addDuration(dur.negated());
|
||||
}
|
||||
|
||||
export fn temporalz_duration_add(handle_a: u32, handle_b: u32) u32 {
|
||||
clearLastError();
|
||||
const a = getDuration(handle_a) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const b = getDuration(handle_b) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const res = a.add(b) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return addDuration(res);
|
||||
}
|
||||
|
||||
export fn temporalz_duration_subtract(handle_a: u32, handle_b: u32) u32 {
|
||||
clearLastError();
|
||||
const a = getDuration(handle_a) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const b = getDuration(handle_b) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const res = a.subtract(b) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return addDuration(res);
|
||||
}
|
||||
|
||||
export fn temporalz_duration_compare(handle_a: u32, handle_b: u32) i32 {
|
||||
clearLastError();
|
||||
const a = getDuration(handle_a) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const b = getDuration(handle_b) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const res = a.compare(b, .{}) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return @intCast(res);
|
||||
}
|
||||
|
||||
export fn temporalz_duration_total(handle: u32, unit_code: u8) f64 {
|
||||
clearLastError();
|
||||
const unit = unitFromCode(unit_code) orelse {
|
||||
setLastErrorMessage("Invalid unit");
|
||||
return 0;
|
||||
};
|
||||
const dur = getDuration(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return dur.total(.{ .unit = unit }) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
export fn temporalz_duration_round(
|
||||
handle: u32,
|
||||
smallest_unit: u8,
|
||||
largest_unit: u8,
|
||||
rounding_mode: u8,
|
||||
rounding_increment: u32,
|
||||
) u32 {
|
||||
clearLastError();
|
||||
const dur = getDuration(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
|
||||
var opts = Temporal.Duration.RoundingOptions{};
|
||||
if (smallest_unit != 255) {
|
||||
opts.smallest_unit = unitFromCode(smallest_unit) orelse {
|
||||
setLastErrorMessage("Invalid smallestUnit");
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
if (largest_unit != 255) {
|
||||
opts.largest_unit = unitFromCode(largest_unit) orelse {
|
||||
setLastErrorMessage("Invalid largestUnit");
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
if (rounding_mode != 255) {
|
||||
opts.rounding_mode = roundingModeFromCode(rounding_mode) orelse {
|
||||
setLastErrorMessage("Invalid roundingMode");
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
if (rounding_increment != 0) {
|
||||
opts.rounding_increment = rounding_increment;
|
||||
}
|
||||
|
||||
const res = dur.round(opts) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return addDuration(res);
|
||||
}
|
||||
|
||||
export fn temporalz_duration_compare_plain_date(handle_a: u32, handle_b: u32, date_handle: u32) i32 {
|
||||
clearLastError();
|
||||
const a = getDuration(handle_a) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const b = getDuration(handle_b) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const date = getPlainDate(date_handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const res = a.compare(b, .{ .relative_to = .{ .plain_date = date } }) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return @intCast(res);
|
||||
}
|
||||
|
||||
export fn temporalz_duration_total_plain_date(handle: u32, unit_code: u8, date_handle: u32) f64 {
|
||||
clearLastError();
|
||||
const unit = unitFromCode(unit_code) orelse {
|
||||
setLastErrorMessage("Invalid unit");
|
||||
return 0;
|
||||
};
|
||||
const dur = getDuration(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const date = getPlainDate(date_handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return dur.total(.{ .unit = unit, .relative_to = .{ .plain_date = date } }) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
|
||||
export fn temporalz_duration_round_plain_date(
|
||||
handle: u32,
|
||||
smallest_unit: u8,
|
||||
largest_unit: u8,
|
||||
rounding_mode: u8,
|
||||
rounding_increment: u32,
|
||||
date_handle: u32,
|
||||
) u32 {
|
||||
clearLastError();
|
||||
const dur = getDuration(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const date = getPlainDate(date_handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
|
||||
var opts = Temporal.Duration.RoundingOptions{};
|
||||
if (smallest_unit != 255) {
|
||||
opts.smallest_unit = unitFromCode(smallest_unit) orelse {
|
||||
setLastErrorMessage("Invalid smallestUnit");
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
if (largest_unit != 255) {
|
||||
opts.largest_unit = unitFromCode(largest_unit) orelse {
|
||||
setLastErrorMessage("Invalid largestUnit");
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
if (rounding_mode != 255) {
|
||||
opts.rounding_mode = roundingModeFromCode(rounding_mode) orelse {
|
||||
setLastErrorMessage("Invalid roundingMode");
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
if (rounding_increment != 0) {
|
||||
opts.rounding_increment = rounding_increment;
|
||||
}
|
||||
opts.relative_to = .{ .plain_date = date };
|
||||
|
||||
const res = dur.round(opts) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return addDuration(res);
|
||||
}
|
||||
|
||||
export fn temporalz_plain_date_from_utf8(ptr: [*]const u8, len: usize) u32 {
|
||||
clearLastError();
|
||||
const text = ptr[0..len];
|
||||
const date = Temporal.PlainDate.from(text) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return addPlainDate(date);
|
||||
}
|
||||
|
||||
export fn temporalz_plain_date_init(year: i32, month: u8, day: u8) u32 {
|
||||
clearLastError();
|
||||
const date = Temporal.PlainDate.init(year, month, day) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return addPlainDate(date);
|
||||
}
|
||||
|
||||
export fn temporalz_plain_date_to_string(handle: u32) u64 {
|
||||
clearLastError();
|
||||
const date = getPlainDate(handle) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
const text = date.toString(wasm_allocator, .{}) catch |err| {
|
||||
setLastError(err);
|
||||
return 0;
|
||||
};
|
||||
return packPtrLen(text.ptr, text.len);
|
||||
}
|
||||
|
||||
export fn temporalz_plain_date_destroy(handle: u32) void {
|
||||
removePlainDate(handle);
|
||||
}
|
||||
|
||||
export fn temporalz_duration_destroy(handle: u32) void {
|
||||
removeDuration(handle);
|
||||
}
|
||||
|
||||
extern fn console(ptr: [*]u8, len: u32) void;
|
||||
|
||||
fn logFn(comptime _: anytype, comptime _: anytype, comptime format: []const u8, args: anytype) void {
|
||||
const formatted = std.fmt.allocPrint(std.heap.wasm_allocator, format, args) catch return;
|
||||
console(formatted.ptr, formatted.len);
|
||||
}
|
||||
|
||||
pub const std_options: std.Options = .{ .logFn = logFn };
|
||||
144
lib/build.zig
144
lib/build.zig
|
|
@ -1,144 +0,0 @@
|
|||
const std = @import("std");
|
||||
const targets = @import("targets.zig");
|
||||
|
||||
pub fn build(b: *std.Build) !void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const force_build_rust = b.option(bool, "build-rust", "Always build Rust library from source") orelse false;
|
||||
|
||||
const arch_str = @tagName(target.result.cpu.arch);
|
||||
const os_str = @tagName(target.result.os.tag);
|
||||
const abi = target.result.abi;
|
||||
const target_triple = if (abi == .none)
|
||||
b.fmt("{s}-{s}", .{ arch_str, os_str })
|
||||
else
|
||||
b.fmt("{s}-{s}-{s}", .{ arch_str, os_str, @tagName(abi) });
|
||||
const prebuilt_name = targets.prebuiltName(b, target);
|
||||
|
||||
const lib_name = if (target.result.os.tag == .windows and abi == .msvc)
|
||||
"temporal_capi.lib"
|
||||
else
|
||||
"libtemporal_capi.a";
|
||||
|
||||
// --- Module --- //
|
||||
const is_freestanding = target.result.os.tag == .freestanding;
|
||||
const mod = b.addModule("libtemporal", .{
|
||||
.root_source_file = b.path("src/root.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.link_libc = !is_freestanding,
|
||||
});
|
||||
|
||||
const temporal_rs = b.dependency("temporal_rs", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
const translated = b.addTranslateC(.{
|
||||
.root_source_file = b.path("src/lib.h"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.link_libc = false,
|
||||
});
|
||||
translated.addIncludePath(temporal_rs.path("temporal_capi/bindings/c"));
|
||||
translated.addIncludePath(b.path("src/stubs/c_headers"));
|
||||
mod.addImport("lib", translated.createModule());
|
||||
|
||||
// --- Rust Misc Deps --- //
|
||||
if (target.result.os.tag == .windows) mod.linkSystemLibrary("userenv", .{});
|
||||
const unwind_stubs = b.addLibrary(.{ .linkage = .static, .name = "unwind_stubs", .root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/stubs/unwind.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}) });
|
||||
mod.linkLibrary(unwind_stubs);
|
||||
|
||||
// --- Steps: update prebuilt dependency hashes --- //
|
||||
{
|
||||
const update_step = b.step("update", "Fetch prebuilt packages and update build.zig.zon");
|
||||
addPrebuiltDependencyFetches(b, update_step);
|
||||
}
|
||||
|
||||
// --- Static lib resolution (prebuilt or source) --- //
|
||||
var selected_lib_file: std.Build.LazyPath = undefined;
|
||||
|
||||
if (!force_build_rust and targets.isDeclared(prebuilt_name)) {
|
||||
const prebuilt_dep = b.lazyDependency(prebuilt_name, .{}) orelse {
|
||||
return;
|
||||
};
|
||||
// std.log.info("using prebuilt libtemporal for {s}", .{prebuilt_name});
|
||||
selected_lib_file = prebuilt_dep.path(lib_name);
|
||||
} else {
|
||||
std.log.info("building libtemporal from source for {s}, requires Rust toolchain", .{target_triple});
|
||||
const build_crab = @import("build_crab");
|
||||
|
||||
var zig_target = target.result;
|
||||
if (zig_target.os.tag == .windows) zig_target.abi = .gnu;
|
||||
const rust_target_str: []const u8 = if (zig_target.cpu.arch == .arm and zig_target.os.tag == .linux)
|
||||
switch (zig_target.abi) {
|
||||
.gnueabihf, .eabihf => "armv7-unknown-linux-gnueabihf",
|
||||
.gnueabi, .eabi => "armv7-unknown-linux-gnueabi",
|
||||
.musleabihf => "armv7-unknown-linux-musleabihf",
|
||||
.musleabi => "armv7-unknown-linux-musleabi",
|
||||
else => "armv7-unknown-linux-gnueabihf",
|
||||
}
|
||||
else blk: {
|
||||
const rust_target = build_crab.rust.Target.fromZig(zig_target) catch
|
||||
@panic("unable to convert target triple to Rust");
|
||||
break :blk b.fmt("{f}", .{rust_target});
|
||||
};
|
||||
const build_dir = build_crab.addCargoBuild(
|
||||
b,
|
||||
.{
|
||||
.manifest_path = b.path("Cargo.toml"),
|
||||
.cargo_args = if (optimize == .Debug) &.{} else &.{"--release"},
|
||||
.rust_target = .{ .value = rust_target_str },
|
||||
},
|
||||
.{
|
||||
.optimize = .ReleaseSafe,
|
||||
},
|
||||
);
|
||||
selected_lib_file = build_dir.path(b, lib_name);
|
||||
}
|
||||
|
||||
mod.addObjectFile(selected_lib_file);
|
||||
|
||||
// --- Install Step (for publishing) --- //
|
||||
const install_lib = b.addInstallFile(selected_lib_file, b.fmt("lib/{s}/{s}", .{ prebuilt_name, lib_name }));
|
||||
b.getInstallStep().dependOn(&install_lib.step);
|
||||
}
|
||||
|
||||
fn addPrebuiltDependencyFetches(b: *std.Build, parent: *std.Build.Step) void {
|
||||
var prev_save: ?*std.Build.Step = null;
|
||||
|
||||
inline for (targets.config.targets) |target_triple| {
|
||||
const url = targets.releaseUrl(b, target_triple);
|
||||
|
||||
const fetch = b.addSystemCommand(&.{ b.graph.zig_exe, "fetch", url });
|
||||
fetch.setName(b.fmt("fetch {s}", .{target_triple}));
|
||||
fetch.setCwd(b.path("."));
|
||||
fetch.has_side_effects = true;
|
||||
fetch.expectExitCode(0);
|
||||
_ = fetch.captureStdErr(.{});
|
||||
|
||||
const save = b.addSystemCommand(&.{
|
||||
b.graph.zig_exe,
|
||||
"fetch",
|
||||
b.fmt("--save={s}", .{target_triple}),
|
||||
url,
|
||||
});
|
||||
save.setName(b.fmt("save {s}", .{target_triple}));
|
||||
save.setCwd(b.path("."));
|
||||
save.has_side_effects = true;
|
||||
save.expectExitCode(0);
|
||||
_ = save.captureStdErr(.{});
|
||||
|
||||
save.step.dependOn(&fetch.step);
|
||||
|
||||
if (prev_save) |prev| {
|
||||
save.step.dependOn(prev);
|
||||
}
|
||||
parent.dependOn(&save.step);
|
||||
prev_save = &save.step;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
.{
|
||||
.name = .libtemporal,
|
||||
.version = "0.2.4",
|
||||
.fingerprint = 0xded01f16f20c2a64,
|
||||
.dependencies = .{
|
||||
.temporal_rs = .{
|
||||
.url = "git+https://github.com/boa-dev/temporal?ref=v0.2.4#a5cebbcce231552bf6ed985d7ea13b0c7b195f02",
|
||||
.hash = "N-V-__8AALjnOQBiCk4NffYgEewZ5v9qlLlDyXO22FIyzNdf",
|
||||
},
|
||||
.build_crab = .{
|
||||
.url = "git+https://github.com/nurulhudaapon/build.crab?ref=zig-dev#69a630f8fa9ccca37a8ba2e898e7934e3b5b8fe2",
|
||||
.hash = "build_crab-0.2.1-U0id_zfKAAAvOuam-kPYKMuEQpHuEBjrP96uQCVj94yr",
|
||||
},
|
||||
.@"aarch64-ios" = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.4/aarch64-ios.tar.gz",
|
||||
.hash = "N-V-__8AAJAyaADZvWvrmaGR5reVCH4y8JZ3-Gfxu_9-pcHB",
|
||||
.lazy = true,
|
||||
},
|
||||
.@"aarch64-linux-android" = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.4/aarch64-linux-android.tar.gz",
|
||||
.hash = "N-V-__8AAKYEkwCQonhHp5MAYaRE8IFcWN493Y2a5nqWJmF7",
|
||||
.lazy = true,
|
||||
},
|
||||
.@"aarch64-linux-gnu" = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.4/aarch64-linux-gnu.tar.gz",
|
||||
.hash = "N-V-__8AAGSQjQDYfN0voDb4c1sCM374u570U8hcEJYoAoTc",
|
||||
.lazy = true,
|
||||
},
|
||||
.@"aarch64-linux-musl" = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.4/aarch64-linux-musl.tar.gz",
|
||||
.hash = "N-V-__8AAE7bjwA2arkXXgbgaMe8oHdmJEez8y2XFeCUvSnn",
|
||||
.lazy = true,
|
||||
},
|
||||
.@"aarch64-macos" = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.4/aarch64-macos.tar.gz",
|
||||
.hash = "N-V-__8AAFBxZwC9MEuiOD8EihBoSl_00IDUJnpQsjmnpkmK",
|
||||
.lazy = true,
|
||||
},
|
||||
.@"aarch64-windows-gnu" = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.4/aarch64-windows-gnu.tar.gz",
|
||||
.hash = "N-V-__8AADKDagD1bmYDywq4IZPBo2la8m1xzSObPCsxyfmW",
|
||||
.lazy = true,
|
||||
},
|
||||
.@"arm-linux-gnueabihf" = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.4/arm-linux-gnueabihf.tar.gz",
|
||||
.hash = "N-V-__8AAIAAfgDYWro4rWudgosfdPK1tzxLe77uoRBtL4rl",
|
||||
.lazy = true,
|
||||
},
|
||||
.@"loongarch64-linux-gnu" = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.4/loongarch64-linux-gnu.tar.gz",
|
||||
.hash = "N-V-__8AAEKptADVBZFKw7ZKvLurwzp_WA-FD-OwZFgEMf4q",
|
||||
.lazy = true,
|
||||
},
|
||||
.@"powerpc64le-linux-gnu" = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.4/powerpc64le-linux-gnu.tar.gz",
|
||||
.hash = "N-V-__8AAKwdfQDZIHVuhOtUOs9tKx-RJCM_1HnX-FwGA0l2",
|
||||
.lazy = true,
|
||||
},
|
||||
.@"riscv64-linux-gnu" = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.4/riscv64-linux-gnu.tar.gz",
|
||||
.hash = "N-V-__8AAPBiogBQe_5VZhzDgpZrfwuzfj_54IyUFK2igsQo",
|
||||
.lazy = true,
|
||||
},
|
||||
.@"s390x-linux-gnu" = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.4/s390x-linux-gnu.tar.gz",
|
||||
.hash = "N-V-__8AAEiKkwC4qkNJoOuzgxHuS_q46SIbqITuODu9Hz3Q",
|
||||
.lazy = true,
|
||||
},
|
||||
.@"wasm32-freestanding" = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.4/wasm32-freestanding.tar.gz",
|
||||
.hash = "N-V-__8AACjsTwB3jX1mva0svtTn39kCz5aabikQbczLJlp9",
|
||||
.lazy = true,
|
||||
},
|
||||
.@"wasm32-wasi" = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.4/wasm32-wasi.tar.gz",
|
||||
.hash = "N-V-__8AAPbTQADoTDaLXmk3KlebN5pZWX-eXhD6BLPJuxpt",
|
||||
.lazy = true,
|
||||
},
|
||||
.@"x86-linux-gnu" = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.4/x86-linux-gnu.tar.gz",
|
||||
.hash = "N-V-__8AALzUbwBdOV8TmU7vPbofrSgkCz70GG0SwvHZGWEZ",
|
||||
.lazy = true,
|
||||
},
|
||||
.@"x86-windows-gnu" = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.4/x86-windows-gnu.tar.gz",
|
||||
.hash = "N-V-__8AAAgSYQAjy_QNLkxQurUPnbT8s4fNjunaYgPQjiwB",
|
||||
.lazy = true,
|
||||
},
|
||||
.@"x86_64-freebsd" = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.4/x86_64-freebsd.tar.gz",
|
||||
.hash = "N-V-__8AAJAFkQCAz3khARx91vZb6HMPqV3oBdmJM8kaxd9Y",
|
||||
.lazy = true,
|
||||
},
|
||||
.@"x86_64-linux-gnu" = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.4/x86_64-linux-gnu.tar.gz",
|
||||
.hash = "N-V-__8AACAdiQB3WUysJXS42gsJZdpzna_04l6omEQGzJZa",
|
||||
.lazy = true,
|
||||
},
|
||||
.@"x86_64-linux-musl" = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.4/x86_64-linux-musl.tar.gz",
|
||||
.hash = "N-V-__8AAGhKiwDlW7Ecy5CJf7-PEGSdDgr4VnCNLkl9cery",
|
||||
.lazy = true,
|
||||
},
|
||||
.@"x86_64-macos" = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.4/x86_64-macos.tar.gz",
|
||||
.hash = "N-V-__8AAHDyZwCPo6HVOYeFWas2bcTqi67vJuxoL2huROlC",
|
||||
.lazy = true,
|
||||
},
|
||||
.@"x86_64-netbsd" = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.4/x86_64-netbsd.tar.gz",
|
||||
.hash = "N-V-__8AAL7_lgBmD0lfXqzAxRdjDiPLi6bgLvnVVbQszw3p",
|
||||
.lazy = true,
|
||||
},
|
||||
.@"x86_64-windows-gnu" = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.4/x86_64-windows-gnu.tar.gz",
|
||||
.hash = "N-V-__8AAD5eTQDfQ9ddNZh3g8e6SaA9CnVSQRMozhHs_jWt",
|
||||
.lazy = true,
|
||||
},
|
||||
},
|
||||
.paths = .{
|
||||
"build.zig",
|
||||
"build.zig.zon",
|
||||
"targets.zon",
|
||||
"targets.zig",
|
||||
"src",
|
||||
},
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
pub const config = @import("targets.zon");
|
||||
const manifest = @import("build.zig.zon");
|
||||
|
||||
/// Zig `-Dtarget` triple for the host platform's prebuilt dependency name.
|
||||
pub fn depName() []const u8 {
|
||||
const triple = targetTripleFromBuiltin();
|
||||
if (!isDeclared(triple)) {
|
||||
@compileError(std.fmt.comptimePrint(
|
||||
"no prebuilt libtemporal for host {s}",
|
||||
.{triple},
|
||||
));
|
||||
}
|
||||
return triple;
|
||||
}
|
||||
|
||||
pub fn prebuiltName(b: *std.Build, target: std.Build.ResolvedTarget) []const u8 {
|
||||
const arch = @tagName(target.result.cpu.arch);
|
||||
const os = target.result.os.tag;
|
||||
const abi = target.result.abi;
|
||||
|
||||
if (os == .wasi and (abi == .musl or abi == .none))
|
||||
return b.fmt("{s}-wasi", .{arch});
|
||||
|
||||
if (abi == .none)
|
||||
return b.fmt("{s}-{s}", .{ arch, @tagName(os) });
|
||||
return b.fmt("{s}-{s}-{s}", .{ arch, @tagName(os), @tagName(abi) });
|
||||
}
|
||||
|
||||
pub fn isDeclared(target_triple: []const u8) bool {
|
||||
inline for (config.targets) |supported| {
|
||||
if (std.mem.eql(u8, supported, target_triple)) {
|
||||
return comptime @hasField(@TypeOf(manifest.dependencies), supported);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn releaseUrl(b: *std.Build, target_triple: []const u8) []const u8 {
|
||||
return b.fmt(
|
||||
"https://github.com/nurulhudaapon/temporalz/releases/download/v{s}/{s}.tar.gz",
|
||||
.{ config.version, target_triple },
|
||||
);
|
||||
}
|
||||
|
||||
fn targetTripleFromBuiltin() []const u8 {
|
||||
if (builtin.os.tag == .wasi and (builtin.abi == .musl or builtin.abi == .none))
|
||||
return std.fmt.comptimePrint("{s}-wasi", .{@tagName(builtin.cpu.arch)});
|
||||
|
||||
const abi = builtin.abi;
|
||||
return if (abi == .none)
|
||||
std.fmt.comptimePrint("{s}-{s}", .{ @tagName(builtin.cpu.arch), @tagName(builtin.os.tag) })
|
||||
else
|
||||
std.fmt.comptimePrint("{s}-{s}-{s}", .{ @tagName(builtin.cpu.arch), @tagName(builtin.os.tag), @tagName(abi) });
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
.{
|
||||
.version = "0.2.4",
|
||||
.targets = .{
|
||||
"x86_64-macos",
|
||||
"aarch64-macos",
|
||||
"x86_64-linux-gnu",
|
||||
"aarch64-linux-gnu",
|
||||
"x86-linux-gnu",
|
||||
"arm-linux-gnueabihf",
|
||||
"loongarch64-linux-gnu",
|
||||
"powerpc64le-linux-gnu",
|
||||
"riscv64-linux-gnu",
|
||||
"s390x-linux-gnu",
|
||||
"x86_64-windows-gnu",
|
||||
"aarch64-windows-gnu",
|
||||
"x86-windows-gnu",
|
||||
"x86_64-freebsd",
|
||||
"x86_64-netbsd",
|
||||
"wasm32-freestanding",
|
||||
"wasm32-wasi",
|
||||
"x86_64-linux-musl",
|
||||
"aarch64-linux-musl",
|
||||
"aarch64-linux-android",
|
||||
"aarch64-ios",
|
||||
},
|
||||
}
|
||||
0
lib/Cargo.lock → pkg/temporal/Cargo.lock
generated
0
lib/Cargo.lock → pkg/temporal/Cargo.lock
generated
94
pkg/temporal/build.zig
Normal file
94
pkg/temporal/build.zig
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) !void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const force_build_rust = b.option(bool, "build-rust", "Always build Rust library from source") orelse false;
|
||||
|
||||
const arch_str = @tagName(target.result.cpu.arch);
|
||||
const os_str = @tagName(target.result.os.tag);
|
||||
const abi = target.result.abi;
|
||||
const target_triple = if (abi == .none)
|
||||
b.fmt("{s}-{s}", .{ arch_str, os_str })
|
||||
else
|
||||
b.fmt("{s}-{s}-{s}", .{ arch_str, os_str, @tagName(abi) });
|
||||
|
||||
const lib_name = if (target.result.os.tag == .windows and abi == .msvc)
|
||||
"temporal_capi.lib"
|
||||
else
|
||||
"libtemporal_capi.a";
|
||||
|
||||
const prebuilt_lib_path = b.fmt("{s}/{s}", .{ target_triple, lib_name });
|
||||
|
||||
// --- Pre-built resolution --- //
|
||||
var prebuilt_lib_file: ?std.Build.LazyPath = null;
|
||||
var selected_lib_file: std.Build.LazyPath = undefined;
|
||||
|
||||
if (!force_build_rust) {
|
||||
const libtemporal_dep = b.lazyDependency("libtemporal", .{});
|
||||
if (libtemporal_dep) |dep| {
|
||||
const lib_file_candidate = dep.path(prebuilt_lib_path);
|
||||
const lib_full_path = lib_file_candidate.getPath(b);
|
||||
if (std.Io.Dir.cwd().openFile(b.graph.io, lib_full_path, .{})) |lib_check_file| {
|
||||
lib_check_file.close(b.graph.io);
|
||||
prebuilt_lib_file = lib_file_candidate;
|
||||
} else |_| {}
|
||||
}
|
||||
}
|
||||
|
||||
if (prebuilt_lib_file) |plf| {
|
||||
// std.debug.print("Using pre-built temporal_capi library from downloaded artifact at: {s}\n", .{prebuilt_lib_path});
|
||||
selected_lib_file = plf;
|
||||
} else {
|
||||
// std.debug.print("building from source: {s}\n", .{prebuilt_lib_path});
|
||||
const build_crab = @import("build_crab");
|
||||
const build_dir = build_crab.addCargoBuild(
|
||||
b,
|
||||
.{
|
||||
.manifest_path = b.path("Cargo.toml"),
|
||||
.cargo_args = if (optimize == .Debug) &.{} else &.{"--release"},
|
||||
},
|
||||
.{
|
||||
.target = target,
|
||||
.optimize = .ReleaseSafe,
|
||||
},
|
||||
);
|
||||
selected_lib_file = build_dir.path(b, lib_name);
|
||||
}
|
||||
|
||||
// --- Install Step (for publishing) --- //
|
||||
const install_lib = b.addInstallFile(selected_lib_file, b.fmt("lib/{s}/{s}", .{ target_triple, lib_name }));
|
||||
b.getInstallStep().dependOn(&install_lib.step);
|
||||
|
||||
// --- Zig Module --- //
|
||||
const mod = b.addModule("temporal_rs", .{
|
||||
.root_source_file = b.path("src/root.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
const temporal_rs = b.dependency("temporal_rs", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
const translated = b.addTranslateC(.{
|
||||
.root_source_file = b.path("src/lib.h"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.link_libc = false,
|
||||
});
|
||||
translated.addIncludePath(temporal_rs.path("temporal_capi/bindings/c"));
|
||||
translated.addIncludePath(b.path("src/stubs/c_headers"));
|
||||
mod.addImport("lib", translated.createModule());
|
||||
mod.addObjectFile(selected_lib_file);
|
||||
|
||||
// --- Rust Misc Deps --- //
|
||||
if (target.result.os.tag == .windows) mod.linkSystemLibrary("userenv", .{});
|
||||
const unwind_stubs = b.addLibrary(.{ .linkage = .static, .name = "unwind_stubs", .root_module = b.createModule(.{
|
||||
.root_source_file = b.path("src/stubs/unwind.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}) });
|
||||
mod.linkLibrary(unwind_stubs);
|
||||
}
|
||||
26
pkg/temporal/build.zig.zon
Normal file
26
pkg/temporal/build.zig.zon
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
.{
|
||||
.name = .temporal,
|
||||
.version = "0.2.0",
|
||||
.fingerprint = 0xd5dcf3f41df6b117,
|
||||
.minimum_zig_version = "0.17.0-dev.387+31f157d80",
|
||||
.dependencies = .{
|
||||
.temporal_rs = .{
|
||||
.url = "git+https://github.com/boa-dev/temporal?ref=v0.2.3#c003cc92325e19b26f8ee2f85e4a47d98cbcc781",
|
||||
.hash = "N-V-__8AAPLKOQDfJ5TYhiiy_6a_dZqUmo9K4e8Xhjfup3fd",
|
||||
},
|
||||
.libtemporal = .{
|
||||
.url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.2.3/libtemporal.tar.gz",
|
||||
.hash = "N-V-__8AAIwh2AUYrkLbf6RU87sNN1tKAQ4qt1kqOwZXNld8",
|
||||
.lazy = true,
|
||||
},
|
||||
.build_crab = .{
|
||||
.url = "git+https://github.com/nurulhudaapon/build.crab?ref=zig-dev#48706bf535be39c87df6aeafcc14b946d174bb50",
|
||||
.hash = "build_crab-0.2.1-U0id_ybJAABQczZZ4_zdQnkJuZF9WLQoHkkrY5TTq4bR",
|
||||
},
|
||||
},
|
||||
.paths = .{
|
||||
"build.zig",
|
||||
"build.zig.zon",
|
||||
"src",
|
||||
},
|
||||
}
|
||||
|
|
@ -8,8 +8,7 @@ const ZonedDateTime = @import("ZonedDateTime.zig");
|
|||
|
||||
/// The `Temporal.Duration` object represents a difference between two time points, which can be used in date/time arithmetic.
|
||||
/// It is fundamentally represented as a combination of years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, and nanoseconds values.
|
||||
///
|
||||
/// See: [Temporal.Duration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration
|
||||
const Duration = @This();
|
||||
|
||||
_inner: *abi.c.Duration,
|
||||
|
|
@ -41,8 +40,7 @@ pub const RoundingOptions = struct {
|
|||
|
||||
/// Partial duration specification for creating Duration objects.
|
||||
/// This is a wrapper around the C API type to avoid exposing C types directly.
|
||||
///
|
||||
/// See: [Temporal.Duration.from](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/from)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/from
|
||||
pub const PartialDuration = struct {
|
||||
years: ?i64 = null,
|
||||
months: ?i64 = null,
|
||||
|
|
@ -57,8 +55,7 @@ pub const PartialDuration = struct {
|
|||
};
|
||||
|
||||
/// Relative-to context for duration operations, used for balancing and calendar-aware math.
|
||||
///
|
||||
/// See: [Temporal.Duration#calendar_durations](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration#calendar_durations)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration#calendar_durations
|
||||
pub const RelativeTo = union(enum) {
|
||||
plain_date: PlainDate,
|
||||
plain_date_time: PlainDateTime,
|
||||
|
|
@ -81,8 +78,7 @@ pub const CompareOptions = struct {
|
|||
|
||||
/// Construct a Duration from years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, and nanoseconds.
|
||||
/// Equivalent to `Temporal.Duration()` constructor.
|
||||
///
|
||||
/// See: [Temporal.Duration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/Duration)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/Duration
|
||||
pub fn init(
|
||||
years_val: i64,
|
||||
months_val: i64,
|
||||
|
|
@ -168,122 +164,105 @@ fn isTimeWithinRange(self: Duration) bool {
|
|||
}
|
||||
|
||||
/// Returns the number of years in the duration.
|
||||
///
|
||||
/// See: [Temporal.Duration.years](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/years)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/years
|
||||
pub fn years(self: Duration) i64 {
|
||||
return abi.c.temporal_rs_Duration_years(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the number of months in the duration.
|
||||
///
|
||||
/// See: [Temporal.Duration.months](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/months)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/months
|
||||
pub fn months(self: Duration) i64 {
|
||||
return abi.c.temporal_rs_Duration_months(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the number of weeks in the duration.
|
||||
///
|
||||
/// See: [Temporal.Duration.weeks](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/weeks)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/weeks
|
||||
pub fn weeks(self: Duration) i64 {
|
||||
return abi.c.temporal_rs_Duration_weeks(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the number of days in the duration.
|
||||
///
|
||||
/// See: [Temporal.Duration.days](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/days)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/days
|
||||
pub fn days(self: Duration) i64 {
|
||||
return abi.c.temporal_rs_Duration_days(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the number of hours in the duration.
|
||||
///
|
||||
/// See: [Temporal.Duration.hours](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/hours)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/hours
|
||||
pub fn hours(self: Duration) i64 {
|
||||
return abi.c.temporal_rs_Duration_hours(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the number of minutes in the duration.
|
||||
///
|
||||
/// See: [Temporal.Duration.minutes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/minutes)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/minutes
|
||||
pub fn minutes(self: Duration) i64 {
|
||||
return abi.c.temporal_rs_Duration_minutes(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the number of seconds in the duration.
|
||||
///
|
||||
/// See: [Temporal.Duration.seconds](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/seconds)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/seconds
|
||||
pub fn seconds(self: Duration) i64 {
|
||||
return abi.c.temporal_rs_Duration_seconds(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the number of milliseconds in the duration.
|
||||
///
|
||||
/// See: [Temporal.Duration.milliseconds](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/milliseconds)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/milliseconds
|
||||
pub fn milliseconds(self: Duration) i64 {
|
||||
return abi.c.temporal_rs_Duration_milliseconds(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the number of microseconds in the duration.
|
||||
///
|
||||
/// See: [Temporal.Duration.microseconds](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/microseconds)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/microseconds
|
||||
pub fn microseconds(self: Duration) f64 {
|
||||
return abi.c.temporal_rs_Duration_microseconds(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the number of nanoseconds in the duration.
|
||||
///
|
||||
/// See: [Temporal.Duration.nanoseconds](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/nanoseconds)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/nanoseconds
|
||||
pub fn nanoseconds(self: Duration) f64 {
|
||||
return abi.c.temporal_rs_Duration_nanoseconds(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the sign of the duration: positive (1), zero (0), or negative (-1).
|
||||
///
|
||||
/// See: [Temporal.Duration.sign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/sign)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/sign
|
||||
pub fn sign(self: Duration) Sign {
|
||||
return abi.from.sign(abi.c.temporal_rs_Duration_sign(self._inner));
|
||||
}
|
||||
|
||||
/// Returns true if the duration is zero (all fields are zero), false otherwise.
|
||||
///
|
||||
/// See: [Temporal.Duration.blank](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/blank)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/blank
|
||||
pub fn blank(self: Duration) bool {
|
||||
return abi.c.temporal_rs_Duration_is_zero(self._inner);
|
||||
}
|
||||
|
||||
/// Returns a new Duration with the absolute value (all components positive).
|
||||
///
|
||||
/// See: [Temporal.Duration.abs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/abs)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/abs
|
||||
pub fn abs(self: Duration) Duration {
|
||||
const ptr: *abi.c.Duration = abi.c.temporal_rs_Duration_abs(self._inner) orelse unreachable;
|
||||
return .{ ._inner = ptr };
|
||||
}
|
||||
|
||||
/// Returns a new Duration with all components negated (sign reversed).
|
||||
///
|
||||
/// See: [Temporal.Duration.negated](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/negated)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/negated
|
||||
pub fn negated(self: Duration) Duration {
|
||||
const ptr: *abi.c.Duration = abi.c.temporal_rs_Duration_negated(self._inner) orelse unreachable;
|
||||
return .{ ._inner = ptr };
|
||||
}
|
||||
|
||||
/// Returns a new Duration with the sum of this duration and another (balanced as needed).
|
||||
///
|
||||
/// See: [Temporal.Duration.add](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/add)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/add
|
||||
pub fn add(self: Duration, other: Duration) !Duration {
|
||||
return wrapDuration(abi.c.temporal_rs_Duration_add(self._inner, other._inner));
|
||||
}
|
||||
|
||||
/// Returns a new Duration with the difference between this duration and another (balanced as needed).
|
||||
///
|
||||
/// See: [Temporal.Duration.subtract](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/subtract)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/subtract
|
||||
pub fn subtract(self: Duration, other: Duration) !Duration {
|
||||
return wrapDuration(abi.c.temporal_rs_Duration_subtract(self._inner, other._inner));
|
||||
}
|
||||
|
||||
/// Returns a new Duration rounded to the given smallest/largest unit and/or balanced.
|
||||
///
|
||||
/// See: [Temporal.Duration.round](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/round)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/round
|
||||
pub fn round(self: Duration, options: RoundingOptions) !Duration {
|
||||
const rel = if (options.relative_to) |r| abi.to.durRelativeTo(r) else abi.c.RelativeTo{ .date = null, .zoned = null };
|
||||
return wrapDuration(abi.c.temporal_rs_Duration_round(self._inner, abi.to.durRoundingOpts(options), rel));
|
||||
|
|
@ -295,8 +274,7 @@ fn roundWithProvider(self: Duration, options: RoundingOptions, relative_to: Rela
|
|||
}
|
||||
|
||||
/// Compares two durations, returning -1, 0, or 1 if this duration is shorter, equal, or longer than the other.
|
||||
///
|
||||
/// See: [Temporal.Duration.compare](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/compare)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/compare
|
||||
pub fn compare(self: Duration, other: Duration, options: CompareOptions) !i8 {
|
||||
const rel = if (options.relative_to) |r| abi.to.durRelativeTo(r) else abi.c.RelativeTo{ .date = null, .zoned = null };
|
||||
const res = abi.c.temporal_rs_Duration_compare(self._inner, other._inner, rel);
|
||||
|
|
@ -310,8 +288,7 @@ fn compareWithProvider(self: Duration, other: Duration, relative_to: RelativeTo,
|
|||
}
|
||||
|
||||
/// Returns the total value of the duration in the specified unit.
|
||||
///
|
||||
/// See: [Temporal.Duration.total](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/total)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/total
|
||||
pub fn total(self: Duration, options: TotalOptions) !f64 {
|
||||
const rel = if (options.relative_to) |r| abi.to.durRelativeTo(r) else abi.c.RelativeTo{ .date = null, .zoned = null };
|
||||
const res = abi.c.temporal_rs_Duration_total(self._inner, abi.to.unit(options.unit).?, rel);
|
||||
|
|
@ -326,8 +303,7 @@ fn totalWithProvider(self: Duration, options: TotalOptions, provider: *const abi
|
|||
}
|
||||
|
||||
/// Returns a string representing this duration in the ISO 8601 format.
|
||||
///
|
||||
/// See: [Temporal.Duration.toString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/toString)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/toString
|
||||
pub fn toString(self: Duration, allocator: std.mem.Allocator, options: ToStringRoundingOptions) ![]u8 {
|
||||
var write = abi.DiplomatWrite.init(allocator);
|
||||
defer write.deinit();
|
||||
|
|
@ -339,16 +315,14 @@ pub fn toString(self: Duration, allocator: std.mem.Allocator, options: ToStringR
|
|||
}
|
||||
|
||||
/// Returns a string representing this duration in the ISO 8601 format (same as toString). Intended for JSON serialization.
|
||||
///
|
||||
/// See: [Temporal.Duration.toJSON](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/toJSON)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/toJSON
|
||||
pub fn toJSON(self: Duration, allocator: std.mem.Allocator) ![]u8 {
|
||||
return self.toString(allocator, .{});
|
||||
}
|
||||
|
||||
/// Returns a string with a language-sensitive representation of this duration.
|
||||
/// Not implemented.
|
||||
///
|
||||
/// See: [Temporal.Duration.toLocaleString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/toLocaleString)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration/toLocaleString
|
||||
pub fn toLocaleString(self: Duration, allocator: std.mem.Allocator) ![]u8 {
|
||||
_ = self;
|
||||
_ = allocator;
|
||||
|
|
@ -366,6 +340,8 @@ pub fn deinit(self: Duration) void {
|
|||
abi.c.temporal_rs_Duration_destroy(self._inner);
|
||||
}
|
||||
|
||||
// --- Helpers -----------------------------------------------------------------
|
||||
|
||||
inline fn handleVoidResult(res: anytype) !void {
|
||||
_ = try abi.extractResult(res);
|
||||
}
|
||||
|
|
@ -376,6 +352,8 @@ fn wrapDuration(res: anytype) !Duration {
|
|||
return .{ ._inner = ptr.? };
|
||||
}
|
||||
|
||||
// --- Aliases and enums ------------------------------------------
|
||||
|
||||
const OptionU8 = abi.c.OptionU8;
|
||||
const OptionU32 = abi.c.OptionU32;
|
||||
const OptionI64 = abi.c.OptionI64;
|
||||
|
|
@ -384,6 +362,8 @@ const Precision = abi.c.Precision;
|
|||
const Unit_option = abi.c.Unit_option;
|
||||
const RoundingMode_option = abi.c.RoundingMode_option;
|
||||
|
||||
// --- Tests -------------------------------------------------------------------
|
||||
|
||||
test init {
|
||||
// Create a simple duration: 1 hour, 30 minutes
|
||||
const dur = try Duration.init(0, 0, 0, 0, 1, 30, 0, 0, 0, 0);
|
||||
|
|
@ -687,6 +667,7 @@ test nanoseconds {
|
|||
const ns = dur.nanoseconds();
|
||||
try std.testing.expect(ns > 499 and ns < 501);
|
||||
}
|
||||
|
||||
test sign {
|
||||
const pos = try Duration.from("P1Y");
|
||||
defer pos.deinit();
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@ const ZonedDateTime = @import("ZonedDateTime.zig");
|
|||
|
||||
/// The `Temporal.Instant` object represents a unique point in time, with nanosecond precision.
|
||||
/// It is fundamentally represented as the number of nanoseconds since the Unix epoch (midnight at the beginning of January 1, 1970, UTC), without any time zone or calendar system.
|
||||
///
|
||||
/// See: [Temporal.Instant](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant
|
||||
const Instant = @This();
|
||||
|
||||
_inner: *abi.c.Instant,
|
||||
|
|
@ -27,8 +26,7 @@ pub const DifferenceSettings = t.DifferenceSettings;
|
|||
pub const TimeZone = t.TimeZone;
|
||||
|
||||
/// Options for Instant.toString().
|
||||
///
|
||||
/// See: [Temporal.Instant.toString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/toString)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/toString
|
||||
pub const ToStringOptions = struct {
|
||||
/// Either an integer from 0 to 9, or null for "auto".
|
||||
/// If null (auto), trailing zeros are removed from the fractional seconds.
|
||||
|
|
@ -49,31 +47,26 @@ pub const ToStringOptions = struct {
|
|||
};
|
||||
|
||||
/// Construct an Instant from epoch nanoseconds (Temporal.Instant.fromEpochNanoseconds).
|
||||
///
|
||||
/// See: [Temporal.Instant.fromEpochNanoseconds](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/fromEpochNanoseconds)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/fromEpochNanoseconds
|
||||
pub fn init(epoch_ns: i128) !Instant {
|
||||
return fromEpochNanoseconds(epoch_ns);
|
||||
}
|
||||
|
||||
/// Construct an Instant from epoch milliseconds (Temporal.Instant.fromEpochMilliseconds).
|
||||
///
|
||||
/// See: [Temporal.Instant.fromEpochMilliseconds](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/fromEpochMilliseconds)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/fromEpochMilliseconds
|
||||
pub fn fromEpochMilliseconds(epoch_ms: i64) !Instant {
|
||||
return wrapInstant(abi.c.temporal_rs_Instant_from_epoch_milliseconds(epoch_ms));
|
||||
}
|
||||
|
||||
/// Construct an Instant from epoch nanoseconds (Temporal.Instant.fromEpochNanoseconds).
|
||||
///
|
||||
/// See: [Temporal.Instant.fromEpochNanoseconds](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/fromEpochNanoseconds)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/fromEpochNanoseconds
|
||||
pub fn fromEpochNanoseconds(epoch_ns: i128) !Instant {
|
||||
const parts = abi.toI128Nanoseconds(epoch_ns);
|
||||
|
||||
return wrapInstant(abi.c.temporal_rs_Instant_try_new(parts));
|
||||
}
|
||||
|
||||
/// Parse an RFC 9557 string (Temporal.Instant.from) or from another Temporal.Instant.
|
||||
///
|
||||
/// See: [Temporal.Instant.from](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/from)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/from
|
||||
pub fn from(info: anytype) !Instant {
|
||||
const T = @TypeOf(info);
|
||||
|
||||
|
|
@ -109,59 +102,51 @@ inline fn fromUtf8(text: []const u8) !Instant {
|
|||
}
|
||||
|
||||
/// Returns a new Instant representing this instant moved forward by a given Duration.
|
||||
///
|
||||
/// See: [Temporal.Instant.add](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/add)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/add
|
||||
pub fn add(self: Instant, duration: *Duration) !Instant {
|
||||
return wrapInstant(abi.c.temporal_rs_Instant_add(self._inner, duration._inner));
|
||||
}
|
||||
|
||||
/// Returns a new Instant representing this instant moved backward by a given Duration.
|
||||
///
|
||||
/// See: [Temporal.Instant.subtract](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/subtract)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/subtract
|
||||
pub fn subtract(self: Instant, duration: *Duration) !Instant {
|
||||
return wrapInstant(abi.c.temporal_rs_Instant_subtract(self._inner, duration._inner));
|
||||
}
|
||||
|
||||
/// Returns a Duration representing the difference from this instant until another instant.
|
||||
///
|
||||
/// See: [Temporal.Instant.until](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/until)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/until
|
||||
pub fn until(self: Instant, other: Instant, settings: DifferenceSettings) !Duration {
|
||||
const ptr = (try abi.extractResult(abi.c.temporal_rs_Instant_until(self._inner, other._inner, abi.to.diffsettings(settings)))) orelse return abi.TemporalError.Generic;
|
||||
return .{ ._inner = ptr };
|
||||
}
|
||||
|
||||
/// Returns a Duration representing the difference from another instant until this instant.
|
||||
///
|
||||
/// See: [Temporal.Instant.since](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/since)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/since
|
||||
pub fn since(self: Instant, other: Instant, settings: DifferenceSettings) !Duration {
|
||||
const ptr = (try abi.extractResult(abi.c.temporal_rs_Instant_since(self._inner, other._inner, abi.to.diffsettings(settings)))) orelse return abi.TemporalError.Generic;
|
||||
return .{ ._inner = ptr };
|
||||
}
|
||||
|
||||
/// Returns a new Instant rounded to the given unit.
|
||||
///
|
||||
/// See: [Temporal.Instant.round](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/round)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/round
|
||||
pub fn round(self: Instant, options: RoundingOptions) !Instant {
|
||||
return wrapInstant(abi.c.temporal_rs_Instant_round(self._inner, abi.to.roundingOpts(options)));
|
||||
}
|
||||
|
||||
/// Compares two Instants, returning -1, 0, or 1 if the first is before, equal, or after the second.
|
||||
///
|
||||
/// See: [Temporal.Instant.compare](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/compare)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/compare
|
||||
pub fn compare(a: Instant, b: Instant) i8 {
|
||||
return abi.c.temporal_rs_Instant_compare(a._inner, b._inner);
|
||||
}
|
||||
|
||||
/// Returns true if two Instants are equal (same epoch nanoseconds).
|
||||
///
|
||||
/// See: [Temporal.Instant.equals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/equals)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/equals
|
||||
pub fn equals(a: Instant, b: Instant) bool {
|
||||
return abi.c.temporal_rs_Instant_equals(a._inner, b._inner);
|
||||
}
|
||||
|
||||
/// Returns a string representing this instant in the RFC 9557 format, optionally using a time zone.
|
||||
///
|
||||
/// See: [Temporal.Instant.toString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/toString)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/toString
|
||||
pub fn toString(self: Instant, allocator: std.mem.Allocator, opts: ToStringOptions) ![]u8 {
|
||||
const zone_opt = if (opts.time_zone) |tz| abi.toTimeZoneOption(tz._inner) else abi.toTimeZoneOption(null);
|
||||
const rounding = optsToRounding(opts);
|
||||
|
|
@ -190,22 +175,19 @@ fn toStringWithProvider(self: Instant, allocator: std.mem.Allocator, provider: *
|
|||
}
|
||||
|
||||
/// Returns a string representing this instant in the RFC 9557 format (same as toString). Intended for JSON serialization.
|
||||
///
|
||||
/// See: [Temporal.Instant.toJSON](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/toJSON)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/toJSON
|
||||
pub fn toJSON(self: Instant, allocator: std.mem.Allocator) ![]u8 {
|
||||
return self.toString(allocator, .{});
|
||||
}
|
||||
|
||||
/// Returns a string with a language-sensitive representation of this instant.
|
||||
///
|
||||
/// See: [Temporal.Instant.toLocaleString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/toLocaleString)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/toLocaleString
|
||||
pub fn toLocaleString(self: Instant, allocator: std.mem.Allocator) ![]u8 {
|
||||
return self.toString(allocator, .{});
|
||||
}
|
||||
|
||||
/// Returns a ZonedDateTime representing this instant in the specified time zone using the ISO 8601 calendar system.
|
||||
///
|
||||
/// See: [Temporal.Instant.toZonedDateTimeISO](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/toZonedDateTimeISO)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/toZonedDateTimeISO
|
||||
pub fn toZonedDateTimeISO(self: Instant, zone: TimeZone) !ZonedDateTime {
|
||||
const ptr = (try abi.extractResult(abi.c.temporal_rs_Instant_to_zoned_date_time_iso(self._inner, zone._inner))) orelse return abi.TemporalError.Generic;
|
||||
return .{ ._inner = ptr };
|
||||
|
|
@ -224,15 +206,13 @@ fn clone(self: Instant) Instant {
|
|||
}
|
||||
|
||||
/// Returns the number of milliseconds since the Unix epoch for this instant.
|
||||
///
|
||||
/// See: [Temporal.Instant.epochMilliseconds](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/epochMilliseconds)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/epochMilliseconds
|
||||
pub fn epochMilliseconds(self: Instant) i64 {
|
||||
return abi.c.temporal_rs_Instant_epoch_milliseconds(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the number of nanoseconds since the Unix epoch for this instant.
|
||||
///
|
||||
/// See: [Temporal.Instant.epochNanoseconds](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/epochNanoseconds)
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant/epochNanoseconds
|
||||
pub fn epochNanoseconds(self: Instant) i128 {
|
||||
return abi.fromI128Nanoseconds(abi.c.temporal_rs_Instant_epoch_nanoseconds(self._inner));
|
||||
}
|
||||
|
|
@ -242,6 +222,8 @@ pub fn deinit(self: Instant) void {
|
|||
abi.c.temporal_rs_Instant_destroy(self._inner);
|
||||
}
|
||||
|
||||
// --- Helpers -----------------------------------------------------------------
|
||||
|
||||
fn wrapInstant(res: anytype) !Instant {
|
||||
const ptr = (try abi.extractResult(res)) orelse return abi.TemporalError.Generic;
|
||||
return .{
|
||||
|
|
@ -279,6 +261,8 @@ fn optsToRounding(opts: ToStringOptions) abi.c.ToStringRoundingOptions {
|
|||
};
|
||||
}
|
||||
|
||||
// --- Tests -------------------------------------------------------------------
|
||||
|
||||
test init {
|
||||
const epoch_ns: i128 = 1_704_067_200_000_000_000; // 2024-01-01T00:00:00Z
|
||||
const inst = try Instant.init(epoch_ns);
|
||||
|
|
|
|||
197
src/Now.zig
197
src/Now.zig
|
|
@ -1,17 +1,16 @@
|
|||
const builtin = @import("builtin");
|
||||
const std = @import("std");
|
||||
const Instant = @import("Instant.zig");
|
||||
const PlainDate = @import("PlainDate.zig");
|
||||
const PlainDateTime = @import("PlainDateTime.zig");
|
||||
const PlainTime = @import("PlainTime.zig");
|
||||
const SystemTimeZone = @import("SystemTimeZone.zig");
|
||||
const ZonedDateTime = @import("ZonedDateTime.zig");
|
||||
const abi = @import("abi.zig");
|
||||
|
||||
/// # Temporal.Now
|
||||
///
|
||||
/// The `Temporal.Now` namespace object contains static methods for getting the current time in various formats.
|
||||
///
|
||||
/// See: [Temporal.Now](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Now)
|
||||
/// - [MDN Temporal.Now](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Now)
|
||||
///
|
||||
/// ## Description
|
||||
///
|
||||
|
|
@ -31,7 +30,7 @@ const Now = @This();
|
|||
|
||||
/// Returns the current time as a [`Temporal.Instant`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant) object.
|
||||
///
|
||||
/// See: [Temporal.Now.instant](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Now/instant)
|
||||
/// See: [MDN Temporal.Now.instant](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Now/instant)
|
||||
pub fn instant(io: std.Io) !Instant {
|
||||
const ns = std.Io.Timestamp.now(io, .real).nanoseconds;
|
||||
return Instant.fromEpochNanoseconds(ns);
|
||||
|
|
@ -39,80 +38,123 @@ pub fn instant(io: std.Io) !Instant {
|
|||
|
||||
/// Returns the current date as a [`Temporal.PlainDate`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainDate) object, in the ISO 8601 calendar and the specified time zone.
|
||||
///
|
||||
/// When `time_zone_like` is null, the system time zone is used.
|
||||
///
|
||||
/// See: [Temporal.Now.plainDateISO](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Now/plainDateISO)
|
||||
pub fn plainDateISO(allocator: std.mem.Allocator, io: std.Io, time_zone_like: ?[]const u8) !PlainDate {
|
||||
const time_zone = try resolveTimeZone(allocator, io, time_zone_like);
|
||||
const now = try instant(io);
|
||||
defer now.deinit();
|
||||
|
||||
const ptr = (try abi.extractResult(abi.c.temporal_rs_PlainDate_from_epoch_nanoseconds(
|
||||
abi.toI128Nanoseconds(now.epochNanoseconds()),
|
||||
abi.to.toTimeZone(time_zone),
|
||||
))) orelse return abi.TemporalError.Generic;
|
||||
return .{ ._inner = ptr };
|
||||
/// See: [MDN Temporal.Now.plainDateISO](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Now/plainDateISO)
|
||||
pub fn plainDateISO(io: std.Io) !PlainDate {
|
||||
const now = currentParts(io);
|
||||
return PlainDate.init(now.year, now.month, now.day);
|
||||
}
|
||||
|
||||
/// Returns the current date and time as a [`Temporal.PlainDateTime`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainDateTime) object, in the ISO 8601 calendar and the specified time zone.
|
||||
///
|
||||
/// When `time_zone_like` is null, the system time zone is used.
|
||||
///
|
||||
/// See: [Temporal.Now.plainDateTimeISO](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Now/plainDateTimeISO)
|
||||
pub fn plainDateTimeISO(allocator: std.mem.Allocator, io: std.Io, time_zone_like: ?[]const u8) !PlainDateTime {
|
||||
const time_zone = try resolveTimeZone(allocator, io, time_zone_like);
|
||||
const now = try instant(io);
|
||||
defer now.deinit();
|
||||
|
||||
const ptr = (try abi.extractResult(abi.c.temporal_rs_PlainDateTime_from_epoch_nanoseconds(
|
||||
abi.toI128Nanoseconds(now.epochNanoseconds()),
|
||||
abi.to.toTimeZone(time_zone),
|
||||
))) orelse return abi.TemporalError.Generic;
|
||||
return .{ ._inner = ptr };
|
||||
/// See: [MDN Temporal.Now.plainDateTimeISO](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Now/plainDateTimeISO)
|
||||
pub fn plainDateTimeISO(io: std.Io) !PlainDateTime {
|
||||
const now = currentParts(io);
|
||||
return PlainDateTime.init(
|
||||
now.year,
|
||||
now.month,
|
||||
now.day,
|
||||
now.hour,
|
||||
now.minute,
|
||||
now.second,
|
||||
now.millisecond,
|
||||
now.microsecond,
|
||||
now.nanosecond,
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns the current time as a [`Temporal.PlainTime`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime) object, in the specified time zone.
|
||||
///
|
||||
/// When `time_zone_like` is null, the system time zone is used.
|
||||
///
|
||||
/// See: [Temporal.Now.plainTimeISO](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Now/plainTimeISO)
|
||||
pub fn plainTimeISO(allocator: std.mem.Allocator, io: std.Io, time_zone_like: ?[]const u8) !PlainTime {
|
||||
const zdt = try zonedDateTimeISO(allocator, io, time_zone_like);
|
||||
defer zdt.deinit();
|
||||
return zdt.toPlainTime();
|
||||
/// See: [MDN Temporal.Now.plainTimeISO](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Now/plainTimeISO)
|
||||
pub fn plainTimeISO(io: std.Io) !PlainTime {
|
||||
const now = currentParts(io);
|
||||
return PlainTime.init(
|
||||
now.hour,
|
||||
now.minute,
|
||||
now.second,
|
||||
now.millisecond,
|
||||
now.microsecond,
|
||||
now.nanosecond,
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns a time zone identifier representing the system's current time zone.
|
||||
///
|
||||
/// The caller owns the returned slice and must free it with `allocator`.
|
||||
///
|
||||
/// See: [Temporal.Now.timeZoneId](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Now/timeZoneId)
|
||||
pub fn timeZoneId(allocator: std.mem.Allocator, io: std.Io) ![]const u8 {
|
||||
const time_zone = try SystemTimeZone.timeZone(allocator, io);
|
||||
var write = abi.DiplomatWrite.init(allocator);
|
||||
defer write.deinit();
|
||||
|
||||
abi.c.temporal_rs_TimeZone_identifier(time_zone._inner, &write.inner);
|
||||
return try write.toOwnedSlice();
|
||||
/// See: [MDN Temporal.Now.timeZoneId](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Now/timeZoneId)
|
||||
pub fn timeZoneId() []const u8 {
|
||||
return "UTC";
|
||||
}
|
||||
|
||||
/// Returns the current date and time as a [`Temporal.ZonedDateTime`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime) object, in the ISO 8601 calendar and the specified time zone.
|
||||
///
|
||||
/// When `time_zone_like` is null, the system time zone is used.
|
||||
///
|
||||
/// See: [Temporal.Now.zonedDateTimeISO](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Now/zonedDateTimeISO)
|
||||
pub fn zonedDateTimeISO(allocator: std.mem.Allocator, io: std.Io, time_zone_like: ?[]const u8) !ZonedDateTime {
|
||||
const now = try instant(io);
|
||||
defer now.deinit();
|
||||
const time_zone = try resolveTimeZone(allocator, io, time_zone_like);
|
||||
return ZonedDateTime.fromEpochNanoseconds(now.epochNanoseconds(), time_zone);
|
||||
/// See: [MDN Temporal.Now.zonedDateTimeISO](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Now/zonedDateTimeISO)
|
||||
pub fn zonedDateTimeISO() !ZonedDateTime {
|
||||
const time_zone = try ZonedDateTime.TimeZone.init(timeZoneId());
|
||||
return ZonedDateTime.fromEpochNanoseconds(currentEpochNanoseconds(), time_zone);
|
||||
}
|
||||
|
||||
fn resolveTimeZone(allocator: std.mem.Allocator, io: std.Io, time_zone_like: ?[]const u8) !ZonedDateTime.TimeZone {
|
||||
if (time_zone_like) |id| return ZonedDateTime.TimeZone.init(id);
|
||||
return SystemTimeZone.timeZone(allocator, io);
|
||||
const CurrentParts = struct {
|
||||
year: i32,
|
||||
month: u8,
|
||||
day: u8,
|
||||
hour: u8,
|
||||
minute: u8,
|
||||
second: u8,
|
||||
millisecond: u16,
|
||||
microsecond: u16,
|
||||
nanosecond: u16,
|
||||
};
|
||||
|
||||
fn currentParts(io: std.Io) CurrentParts {
|
||||
const ns = std.Io.Timestamp.now(io, .real).nanoseconds;
|
||||
const seconds: i64 = @intCast(@divTrunc(ns, 1_000_000_000));
|
||||
const subsec_nanos_u64: u64 = @intCast(@rem(ns, 1_000_000_000));
|
||||
|
||||
const days_since_epoch: u64 = @intCast(@divTrunc(seconds, std.time.epoch.secs_per_day));
|
||||
const secs_of_day: u64 = @intCast(@mod(seconds, std.time.epoch.secs_per_day));
|
||||
|
||||
const epoch_day = std.time.epoch.EpochDay{ .day = @intCast(days_since_epoch) };
|
||||
const year_day = epoch_day.calculateYearDay();
|
||||
const month_day = year_day.calculateMonthDay();
|
||||
const day_seconds = std.time.epoch.DaySeconds{ .secs = @intCast(secs_of_day) };
|
||||
|
||||
const millisecond: u16 = @intCast(subsec_nanos_u64 / 1_000_000);
|
||||
const microsecond: u16 = @intCast((subsec_nanos_u64 / 1_000) % 1_000);
|
||||
const nanosecond: u16 = @intCast(subsec_nanos_u64 % 1_000);
|
||||
|
||||
return .{
|
||||
.year = @intCast(year_day.year),
|
||||
.month = @intCast(month_day.month.numeric()),
|
||||
.day = @intCast(month_day.day_index + 1),
|
||||
.hour = @intCast(day_seconds.getHoursIntoDay()),
|
||||
.minute = @intCast(day_seconds.getMinutesIntoHour()),
|
||||
.second = @intCast(day_seconds.getSecondsIntoMinute()),
|
||||
.millisecond = millisecond,
|
||||
.microsecond = microsecond,
|
||||
.nanosecond = nanosecond,
|
||||
};
|
||||
}
|
||||
|
||||
fn currentEpochNanoseconds() i128 {
|
||||
return switch (builtin.os.tag) {
|
||||
.windows => blk: {
|
||||
const epoch_ns = std.time.epoch.windows * std.time.ns_per_s;
|
||||
break :blk @as(i128, @intCast(std.os.windows.ntdll.RtlGetSystemTimePrecise())) * 100 + epoch_ns;
|
||||
},
|
||||
else => blk: {
|
||||
var timespec: std.posix.timespec = undefined;
|
||||
switch (std.posix.errno(std.posix.system.clock_gettime(.REALTIME, ×pec))) {
|
||||
.SUCCESS => {},
|
||||
else => return 0,
|
||||
}
|
||||
|
||||
const seconds: i128 = @intCast(timespec.sec);
|
||||
const nanos: i128 = @intCast(timespec.nsec);
|
||||
break :blk seconds * std.time.ns_per_s + nanos;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// ---------- Tests ---------------------
|
||||
test instant {
|
||||
const io = std.testing.io;
|
||||
const inst = try instant(io);
|
||||
|
|
@ -122,62 +164,37 @@ test instant {
|
|||
|
||||
test plainDateISO {
|
||||
const io = std.testing.io;
|
||||
const date = try plainDateISO(std.testing.allocator, io, null);
|
||||
defer date.deinit();
|
||||
const date = try plainDateISO(io);
|
||||
try std.testing.expect(date.year() >= 1970);
|
||||
try std.testing.expect(date.month() >= 1 and date.month() <= 12);
|
||||
try std.testing.expect(date.day() >= 1 and date.day() <= 31);
|
||||
}
|
||||
|
||||
test plainDateTimeISO {
|
||||
const io = std.testing.io;
|
||||
var dt = try plainDateTimeISO(std.testing.allocator, io, null);
|
||||
defer dt.deinit();
|
||||
const dt = try plainDateTimeISO(io);
|
||||
try std.testing.expect(dt.year() >= 1970);
|
||||
try std.testing.expect(dt.month() >= 1 and dt.month() <= 12);
|
||||
try std.testing.expect(dt.day() >= 1 and dt.day() <= 31);
|
||||
try std.testing.expect(dt.hour() < 24);
|
||||
try std.testing.expect(dt.minute() < 60);
|
||||
}
|
||||
|
||||
test plainTimeISO {
|
||||
const io = std.testing.io;
|
||||
const t = try plainTimeISO(std.testing.allocator, io, null);
|
||||
const t = try plainTimeISO(io);
|
||||
try std.testing.expect(t.hour() < 24);
|
||||
try std.testing.expect(t.minute() < 60);
|
||||
try std.testing.expect(t.second() < 60);
|
||||
}
|
||||
|
||||
test timeZoneId {
|
||||
const io = std.testing.io;
|
||||
const tz = try timeZoneId(std.testing.allocator, io);
|
||||
defer std.testing.allocator.free(tz);
|
||||
try std.testing.expect(tz.len > 0);
|
||||
_ = try ZonedDateTime.TimeZone.init(tz);
|
||||
const tz = timeZoneId();
|
||||
try std.testing.expectEqualStrings("UTC", tz);
|
||||
}
|
||||
|
||||
test zonedDateTimeISO {
|
||||
const io = std.testing.io;
|
||||
const zdt = try zonedDateTimeISO(std.testing.allocator, io, null);
|
||||
const zdt = try zonedDateTimeISO();
|
||||
defer zdt.deinit();
|
||||
|
||||
try std.testing.expect(zdt.epochNanoseconds() > 0);
|
||||
const tz = try zdt.timeZoneId(std.testing.allocator);
|
||||
defer std.testing.allocator.free(tz);
|
||||
const expected_tz = try timeZoneId(std.testing.allocator, io);
|
||||
defer std.testing.allocator.free(expected_tz);
|
||||
try std.testing.expectEqualStrings(expected_tz, tz);
|
||||
}
|
||||
|
||||
test "plainDateISO with explicit time zone" {
|
||||
const io = std.testing.io;
|
||||
const date = try plainDateISO(std.testing.allocator, io, "UTC");
|
||||
defer date.deinit();
|
||||
|
||||
const zdt = try zonedDateTimeISO(std.testing.allocator, io, "UTC");
|
||||
defer zdt.deinit();
|
||||
const plain = try zdt.toPlainDate();
|
||||
defer plain.deinit();
|
||||
|
||||
try std.testing.expect(date.equals(plain));
|
||||
try std.testing.expectEqualStrings("UTC", tz);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ const Duration = @import("Duration.zig");
|
|||
///
|
||||
/// The `Temporal.PlainDate` object represents a calendar date (year, month, day) with no time or time zone.
|
||||
///
|
||||
/// See: [Temporal.PlainDate](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainDate)
|
||||
/// The `Temporal.PlainDate` object represents a calendar date (year, month, day) with no time or time zone.
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainDate
|
||||
const PlainDate = @This();
|
||||
|
||||
/// Internal pointer to the underlying C PlainDate object.
|
||||
|
|
|
|||
|
|
@ -11,7 +11,9 @@ const Duration = @import("Duration.zig");
|
|||
///
|
||||
/// The `Temporal.PlainDateTime` object represents a calendar date and wall-clock time, but no time zone or offset.
|
||||
///
|
||||
/// See: [Temporal.PlainDateTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainDateTime)
|
||||
/// - [MDN Temporal.PlainDateTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainDateTime)
|
||||
/// The `Temporal.PlainDateTime` object represents a calendar date and wall-clock time, but no time zone or offset.
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainDateTime
|
||||
const PlainDateTime = @This();
|
||||
|
||||
/// Internal pointer to the underlying C PlainDateTime object.
|
||||
|
|
@ -545,6 +547,7 @@ fn wrapPlainDateTime(res: anytype) !PlainDateTime {
|
|||
return .{ ._inner = ptr };
|
||||
}
|
||||
|
||||
// ---------- Tests ---------------------
|
||||
test init {
|
||||
const dt = try PlainDateTime.init(2024, 1, 15, 14, 30, 45, 123, 456, 789);
|
||||
try std.testing.expectEqual(@as(i32, 2024), dt.year());
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const PlainDate = @import("PlainDate.zig");
|
|||
///
|
||||
/// The `Temporal.PlainMonthDay` object represents a month and day in a calendar, with no year or time.
|
||||
///
|
||||
/// See: [Temporal.PlainMonthDay](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay)
|
||||
/// - [MDN Temporal.PlainMonthDay](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay)
|
||||
const PlainMonthDay = @This();
|
||||
|
||||
_inner: *abi.c.PlainMonthDay,
|
||||
|
|
@ -39,8 +39,7 @@ fn wrapPlainMonthDay(result: anytype) !PlainMonthDay {
|
|||
|
||||
/// Creates a new PlainMonthDay from the given month, day, and optional calendar.
|
||||
/// Equivalent to the Temporal.PlainMonthDay constructor.
|
||||
///
|
||||
/// See: [Temporal.PlainMonthDay](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/PlainMonthDay)
|
||||
/// See [MDN Temporal.PlainMonthDay() constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/PlainMonthDay)
|
||||
pub fn init(month_val: u8, day_val: u8, calendar: ?[]const u8) !PlainMonthDay {
|
||||
const cal_kind = if (calendar) |cal| blk: {
|
||||
const cal_view = abi.toDiplomatStringView(cal);
|
||||
|
|
@ -61,8 +60,7 @@ pub fn init(month_val: u8, day_val: u8, calendar: ?[]const u8) !PlainMonthDay {
|
|||
}
|
||||
|
||||
/// Parses a PlainMonthDay from a string.
|
||||
///
|
||||
/// See: [Temporal.PlainMonthDay.from](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/from)
|
||||
/// See [MDN Temporal.PlainMonthDay.from()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/from)
|
||||
pub fn from(s: []const u8) !PlainMonthDay {
|
||||
return fromUtf8(s);
|
||||
}
|
||||
|
|
@ -79,16 +77,14 @@ fn fromUtf16(utf16: []const u16) !PlainMonthDay {
|
|||
|
||||
// Comparison
|
||||
/// Returns true if this PlainMonthDay is equal to another (same date and calendar).
|
||||
///
|
||||
/// See: [Temporal.PlainMonthDay.equals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/equals)
|
||||
/// See [MDN Temporal.PlainMonthDay.prototype.equals()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/equals)
|
||||
pub fn equals(self: PlainMonthDay, other: PlainMonthDay) bool {
|
||||
return abi.c.temporal_rs_PlainMonthDay_equals(self._inner, other._inner);
|
||||
}
|
||||
|
||||
// Property accessors
|
||||
/// Returns the calendar identifier used to interpret the internal ISO 8601 date.
|
||||
///
|
||||
/// See: [Temporal.PlainMonthDay.calendarId](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/calendarId)
|
||||
/// See [MDN Temporal.PlainMonthDay.prototype.calendarId](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/calendarId)
|
||||
pub fn calendarId(self: PlainMonthDay, allocator: std.mem.Allocator) ![]u8 {
|
||||
const calendar_ptr = abi.c.temporal_rs_PlainMonthDay_calendar(self._inner) orelse return error.TemporalError;
|
||||
const cal_id_view = abi.c.temporal_rs_Calendar_identifier(calendar_ptr);
|
||||
|
|
@ -96,15 +92,13 @@ pub fn calendarId(self: PlainMonthDay, allocator: std.mem.Allocator) ![]u8 {
|
|||
}
|
||||
|
||||
/// Returns the 1-based day index in the month of this date.
|
||||
///
|
||||
/// See: [Temporal.PlainMonthDay.day](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/day)
|
||||
/// See [MDN Temporal.PlainMonthDay.prototype.day](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/day)
|
||||
pub fn day(self: PlainMonthDay) u8 {
|
||||
return abi.c.temporal_rs_PlainMonthDay_day(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the calendar-specific string representing the month of this date.
|
||||
///
|
||||
/// See: [Temporal.PlainMonthDay.monthCode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/monthCode)
|
||||
/// See [MDN Temporal.PlainMonthDay.prototype.monthCode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/monthCode)
|
||||
pub fn monthCode(self: PlainMonthDay, allocator: std.mem.Allocator) ![]const u8 {
|
||||
var write = abi.DiplomatWrite.init(allocator);
|
||||
defer write.deinit();
|
||||
|
|
@ -115,8 +109,7 @@ pub fn monthCode(self: PlainMonthDay, allocator: std.mem.Allocator) ![]const u8
|
|||
|
||||
// Modification
|
||||
/// Returns a new PlainMonthDay with some fields replaced by new values.
|
||||
///
|
||||
/// See: [Temporal.PlainMonthDay.with](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/with)
|
||||
/// See [MDN Temporal.PlainMonthDay.prototype.with()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/with)
|
||||
pub fn with(self: PlainMonthDay, options: WithOptions) !PlainMonthDay {
|
||||
// Build month_code view
|
||||
const month_code_view = if (options.month_code) |mc|
|
||||
|
|
@ -149,8 +142,7 @@ pub fn with(self: PlainMonthDay, options: WithOptions) !PlainMonthDay {
|
|||
|
||||
// Conversion
|
||||
/// Returns a PlainDate representing this month-day and a supplied year in the same calendar system.
|
||||
///
|
||||
/// See: [Temporal.PlainMonthDay.toPlainDate](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/toPlainDate)
|
||||
/// See [MDN Temporal.PlainMonthDay.prototype.toPlainDate()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/toPlainDate)
|
||||
pub fn toPlainDate(self: PlainMonthDay, year: i32) !PlainDate {
|
||||
const partial_date = abi.c.PartialDate_option{
|
||||
.is_ok = true,
|
||||
|
|
@ -175,8 +167,7 @@ pub fn toPlainDate(self: PlainMonthDay, year: i32) !PlainDate {
|
|||
|
||||
// String conversions
|
||||
/// Returns a string representing this month-day in RFC 9557 format.
|
||||
///
|
||||
/// See: [Temporal.PlainMonthDay.toString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/toString)
|
||||
/// See [MDN Temporal.PlainMonthDay.prototype.toString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/toString)
|
||||
pub fn toString(self: PlainMonthDay, allocator: std.mem.Allocator) ![]u8 {
|
||||
return toStringWithOptions(self, allocator, .{});
|
||||
}
|
||||
|
|
@ -193,27 +184,26 @@ fn toStringWithOptions(self: PlainMonthDay, allocator: std.mem.Allocator, option
|
|||
}
|
||||
|
||||
/// Returns a string representing this month-day in RFC 9557 format (ISO 8601).
|
||||
///
|
||||
/// See: [Temporal.PlainMonthDay.toJSON](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/toJSON)
|
||||
/// See [MDN Temporal.PlainMonthDay.prototype.toJSON()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/toJSON)
|
||||
pub fn toJSON(self: PlainMonthDay, allocator: std.mem.Allocator) ![]u8 {
|
||||
return toString(self, allocator);
|
||||
}
|
||||
|
||||
/// Returns a language-sensitive string representation of this month-day.
|
||||
///
|
||||
/// See: [Temporal.PlainMonthDay.toLocaleString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/toLocaleString)
|
||||
/// See [MDN Temporal.PlainMonthDay.prototype.toLocaleString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/toLocaleString)
|
||||
pub fn toLocaleString(self: PlainMonthDay, allocator: std.mem.Allocator) ![]u8 {
|
||||
return toString(self, allocator);
|
||||
}
|
||||
|
||||
/// Throws an error; valueOf() is not supported for PlainMonthDay.
|
||||
///
|
||||
/// See: [Temporal.PlainMonthDay.valueOf](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/valueOf)
|
||||
/// See [MDN Temporal.PlainMonthDay.prototype.valueOf()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay/valueOf)
|
||||
pub fn valueOf(self: PlainMonthDay) !void {
|
||||
_ = self;
|
||||
return error.ValueError;
|
||||
}
|
||||
|
||||
// ---------- Tests ---------------------
|
||||
|
||||
test init {
|
||||
const md = try init(12, 25, null);
|
||||
try std.testing.expectEqual(@as(u8, 25), md.day());
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const Duration = @import("Duration.zig");
|
|||
///
|
||||
/// The `Temporal.PlainTime` object represents a wall-clock time, with no date or time zone.
|
||||
///
|
||||
/// See: [Temporal.PlainTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime)
|
||||
/// - [MDN Temporal.PlainTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime)
|
||||
const PlainTime = @This();
|
||||
|
||||
_inner: *abi.c.PlainTime,
|
||||
|
|
@ -45,26 +45,18 @@ pub fn init(
|
|||
microsecond_val: u16,
|
||||
nanosecond_val: u16,
|
||||
) !PlainTime {
|
||||
if (hour_val > 23 or minute_val > 59 or second_val > 59 or
|
||||
millisecond_val > 999 or microsecond_val > 999 or nanosecond_val > 999)
|
||||
{
|
||||
return abi.TemporalError.RangeError;
|
||||
}
|
||||
var buf: [18]u8 = undefined;
|
||||
const s = std.fmt.bufPrint(&buf, "{d:0>2}:{d:0>2}:{d:0>2}.{d:0>3}{d:0>3}{d:0>3}", .{
|
||||
return wrapPlainTime(abi.c.temporal_rs_PlainTime_try_new(
|
||||
hour_val,
|
||||
minute_val,
|
||||
second_val,
|
||||
millisecond_val,
|
||||
microsecond_val,
|
||||
nanosecond_val,
|
||||
}) catch unreachable;
|
||||
return from(s);
|
||||
));
|
||||
}
|
||||
|
||||
/// Parses a PlainTime from a string.
|
||||
///
|
||||
/// See: [Temporal.PlainTime.from](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/from)
|
||||
/// See [MDN Temporal.PlainTime.from()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/from)
|
||||
pub fn from(s: []const u8) !PlainTime {
|
||||
return fromUtf8(s);
|
||||
}
|
||||
|
|
@ -81,36 +73,31 @@ fn fromUtf16(utf16: []const u16) !PlainTime {
|
|||
|
||||
/// Compares two PlainTime instances by their time values.
|
||||
/// Returns -1, 0, or 1 if the first is before, equal, or after the second.
|
||||
///
|
||||
/// See: [Temporal.PlainTime.compare](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/compare)
|
||||
/// See [MDN Temporal.PlainTime.compare()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/compare)
|
||||
pub fn compare(a: PlainTime, b: PlainTime) i8 {
|
||||
return abi.c.temporal_rs_PlainTime_compare(a._inner, b._inner);
|
||||
}
|
||||
|
||||
/// Returns true if this PlainTime is equal to another (same time values).
|
||||
///
|
||||
/// See: [Temporal.PlainTime.equals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/equals)
|
||||
/// See [MDN Temporal.PlainTime.prototype.equals()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/equals)
|
||||
pub fn equals(self: PlainTime, other: PlainTime) bool {
|
||||
return abi.c.temporal_rs_PlainTime_equals(self._inner, other._inner);
|
||||
}
|
||||
|
||||
/// Returns a new PlainTime moved forward by the given duration, wrapping around the clock if necessary.
|
||||
///
|
||||
/// See: [Temporal.PlainTime.add](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/add)
|
||||
/// See [MDN Temporal.PlainTime.prototype.add()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/add)
|
||||
pub fn add(self: PlainTime, duration: Duration) !PlainTime {
|
||||
return wrapPlainTime(abi.c.temporal_rs_PlainTime_add(self._inner, duration._inner));
|
||||
}
|
||||
|
||||
/// Returns a new PlainTime moved backward by the given duration, wrapping around the clock if necessary.
|
||||
///
|
||||
/// See: [Temporal.PlainTime.subtract](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/subtract)
|
||||
/// See [MDN Temporal.PlainTime.prototype.subtract()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/subtract)
|
||||
pub fn subtract(self: PlainTime, duration: Duration) !PlainTime {
|
||||
return wrapPlainTime(abi.c.temporal_rs_PlainTime_subtract(self._inner, duration._inner));
|
||||
}
|
||||
|
||||
/// Returns the duration from this PlainTime to another.
|
||||
///
|
||||
/// See: [Temporal.PlainTime.until](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/until)
|
||||
/// See [MDN Temporal.PlainTime.prototype.until()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/until)
|
||||
pub fn until(self: PlainTime, other: PlainTime, options: DifferenceSettings) !Duration {
|
||||
const settings = abi.to.diffsettings(options);
|
||||
const result = abi.c.temporal_rs_PlainTime_until(self._inner, other._inner, settings);
|
||||
|
|
@ -119,8 +106,7 @@ pub fn until(self: PlainTime, other: PlainTime, options: DifferenceSettings) !Du
|
|||
}
|
||||
|
||||
/// Returns the duration from another PlainTime to this one.
|
||||
///
|
||||
/// See: [Temporal.PlainTime.since](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/since)
|
||||
/// See [MDN Temporal.PlainTime.prototype.since()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/since)
|
||||
pub fn since(self: PlainTime, other: PlainTime, options: DifferenceSettings) !Duration {
|
||||
const settings = abi.to.diffsettings(options);
|
||||
const result = abi.c.temporal_rs_PlainTime_since(self._inner, other._inner, settings);
|
||||
|
|
@ -130,59 +116,51 @@ pub fn since(self: PlainTime, other: PlainTime, options: DifferenceSettings) !Du
|
|||
|
||||
// Rounding
|
||||
/// Returns a new PlainTime rounded to the given unit and options.
|
||||
///
|
||||
/// See: [Temporal.PlainTime.round](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/round)
|
||||
/// See [MDN Temporal.PlainTime.prototype.round()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/round)
|
||||
pub fn round(self: PlainTime, options: RoundOptions) !PlainTime {
|
||||
return wrapPlainTime(abi.c.temporal_rs_PlainTime_round(self._inner, abi.to.roundingOpts(options)));
|
||||
}
|
||||
|
||||
// Property accessors
|
||||
/// Returns the hour component of this time (0-23).
|
||||
///
|
||||
/// See: [Temporal.PlainTime.hour](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/hour)
|
||||
/// See [MDN Temporal.PlainTime.prototype.hour](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/hour)
|
||||
pub fn hour(self: PlainTime) u8 {
|
||||
return abi.c.temporal_rs_PlainTime_hour(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the minute component of this time (0-59).
|
||||
///
|
||||
/// See: [Temporal.PlainTime.minute](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/minute)
|
||||
/// See [MDN Temporal.PlainTime.prototype.minute](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/minute)
|
||||
pub fn minute(self: PlainTime) u8 {
|
||||
return abi.c.temporal_rs_PlainTime_minute(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the second component of this time (0-59).
|
||||
///
|
||||
/// See: [Temporal.PlainTime.second](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/second)
|
||||
/// See [MDN Temporal.PlainTime.prototype.second](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/second)
|
||||
pub fn second(self: PlainTime) u8 {
|
||||
return abi.c.temporal_rs_PlainTime_second(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the millisecond component of this time (0-999).
|
||||
///
|
||||
/// See: [Temporal.PlainTime.millisecond](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/millisecond)
|
||||
/// See [MDN Temporal.PlainTime.prototype.millisecond](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/millisecond)
|
||||
pub fn millisecond(self: PlainTime) u16 {
|
||||
return abi.c.temporal_rs_PlainTime_millisecond(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the microsecond component of this time (0-999).
|
||||
///
|
||||
/// See: [Temporal.PlainTime.microsecond](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/microsecond)
|
||||
/// See [MDN Temporal.PlainTime.prototype.microsecond](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/microsecond)
|
||||
pub fn microsecond(self: PlainTime) u16 {
|
||||
return abi.c.temporal_rs_PlainTime_microsecond(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the nanosecond component of this time (0-999).
|
||||
///
|
||||
/// See: [Temporal.PlainTime.nanosecond](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/nanosecond)
|
||||
/// See [MDN Temporal.PlainTime.prototype.nanosecond](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/nanosecond)
|
||||
pub fn nanosecond(self: PlainTime) u16 {
|
||||
return abi.c.temporal_rs_PlainTime_nanosecond(self._inner);
|
||||
}
|
||||
|
||||
// Modification
|
||||
/// Returns a new PlainTime with some fields replaced by new values.
|
||||
///
|
||||
/// See: [Temporal.PlainTime.with](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/with)
|
||||
/// See [MDN Temporal.PlainTime.prototype.with()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/with)
|
||||
pub fn with(self: PlainTime, options: WithOptions) !PlainTime {
|
||||
const partial = abi.c.PartialTime{
|
||||
.hour = abi.toOption(abi.c.OptionU8, options.hour),
|
||||
|
|
@ -201,8 +179,7 @@ pub fn with(self: PlainTime, options: WithOptions) !PlainTime {
|
|||
|
||||
// String conversions
|
||||
/// Returns a string representing this PlainTime in RFC 9557 format.
|
||||
///
|
||||
/// See: [Temporal.PlainTime.toString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/toString)
|
||||
/// See [MDN Temporal.PlainTime.prototype.toString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/toString)
|
||||
pub fn toString(self: PlainTime, allocator: std.mem.Allocator) ![]u8 {
|
||||
return toStringWithOptions(self, allocator, .{});
|
||||
}
|
||||
|
|
@ -224,29 +201,28 @@ fn toStringWithOptions(self: PlainTime, allocator: std.mem.Allocator, options: t
|
|||
}
|
||||
|
||||
/// Returns a string representing this PlainTime in RFC 9557 format (ISO 8601).
|
||||
///
|
||||
/// See: [Temporal.PlainTime.toJSON](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/toJSON)
|
||||
/// See [MDN Temporal.PlainTime.prototype.toJSON()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/toJSON)
|
||||
pub fn toJSON(self: PlainTime, allocator: std.mem.Allocator) ![]u8 {
|
||||
return toString(self, allocator);
|
||||
}
|
||||
|
||||
/// Returns a language-sensitive string representation of this PlainTime.
|
||||
///
|
||||
/// See: [Temporal.PlainTime.toLocaleString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/toLocaleString)
|
||||
/// See [MDN Temporal.PlainTime.prototype.toLocaleString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/toLocaleString)
|
||||
pub fn toLocaleString(self: PlainTime, allocator: std.mem.Allocator) ![]u8 {
|
||||
// For now, just use toString - locale-specific formatting would require more work
|
||||
return toString(self, allocator);
|
||||
}
|
||||
|
||||
/// Throws an error; valueOf() is not supported for PlainTime.
|
||||
///
|
||||
/// See: [Temporal.PlainTime.valueOf](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/valueOf)
|
||||
/// See [MDN Temporal.PlainTime.prototype.valueOf()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime/valueOf)
|
||||
pub fn valueOf(self: PlainTime) !void {
|
||||
_ = self;
|
||||
// PlainTime should not be used in arithmetic/comparison operations implicitly
|
||||
return error.ValueError;
|
||||
}
|
||||
|
||||
// ---------- Tests ---------------------
|
||||
|
||||
test init {
|
||||
{
|
||||
const time = try init(14, 30, 45, 123, 456, 789);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ const Duration = @import("Duration.zig");
|
|||
///
|
||||
/// The `Temporal.PlainYearMonth` object represents a particular month in a specific year, with no day or time.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth)
|
||||
/// - [MDN Temporal.PlainYearMonth](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth)
|
||||
const PlainYearMonth = @This();
|
||||
|
||||
_inner: *abi.c.PlainYearMonth,
|
||||
|
|
@ -47,8 +47,7 @@ fn wrapPlainYearMonth(result: anytype) !PlainYearMonth {
|
|||
|
||||
/// Creates a new PlainYearMonth from the given year, month, and optional calendar.
|
||||
/// Equivalent to the Temporal.PlainYearMonth constructor.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/PlainYearMonth)
|
||||
/// See [MDN Temporal.PlainYearMonth() constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/PlainYearMonth)
|
||||
pub fn init(year_val: i32, month_val: u8, calendar: ?[]const u8) !PlainYearMonth {
|
||||
const cal_kind = if (calendar) |cal| blk: {
|
||||
const cal_view = abi.toDiplomatStringView(cal);
|
||||
|
|
@ -69,8 +68,7 @@ pub fn init(year_val: i32, month_val: u8, calendar: ?[]const u8) !PlainYearMonth
|
|||
}
|
||||
|
||||
/// Parses a PlainYearMonth from a string.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.from](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/from)
|
||||
/// See [MDN Temporal.PlainYearMonth.from()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/from)
|
||||
pub fn from(s: []const u8) !PlainYearMonth {
|
||||
return fromUtf8(s);
|
||||
}
|
||||
|
|
@ -88,39 +86,34 @@ fn fromUtf16(utf16: []const u16) !PlainYearMonth {
|
|||
// Comparison
|
||||
/// Compares two PlainYearMonth instances by their ISO date values.
|
||||
/// Returns -1, 0, or 1 if the first is before, equal, or after the second.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.compare](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/compare)
|
||||
/// See [MDN Temporal.PlainYearMonth.compare()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/compare)
|
||||
pub fn compare(a: PlainYearMonth, b: PlainYearMonth) i8 {
|
||||
return abi.c.temporal_rs_PlainYearMonth_compare(a._inner, b._inner);
|
||||
}
|
||||
|
||||
/// Returns true if this PlainYearMonth is equal to another (same ISO date and calendar).
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.equals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/equals)
|
||||
/// See [MDN Temporal.PlainYearMonth.prototype.equals()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/equals)
|
||||
pub fn equals(self: PlainYearMonth, other: PlainYearMonth) bool {
|
||||
return abi.c.temporal_rs_PlainYearMonth_equals(self._inner, other._inner);
|
||||
}
|
||||
|
||||
// Arithmetic
|
||||
/// Returns a new PlainYearMonth moved forward by the given duration.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.add](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/add)
|
||||
/// See [MDN Temporal.PlainYearMonth.prototype.add()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/add)
|
||||
pub fn add(self: PlainYearMonth, duration: Duration) !PlainYearMonth {
|
||||
const overflow = abi.c.ArithmeticOverflow_Constrain;
|
||||
return wrapPlainYearMonth(abi.c.temporal_rs_PlainYearMonth_add(self._inner, duration._inner, overflow));
|
||||
}
|
||||
|
||||
/// Returns a new PlainYearMonth moved backward by the given duration.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.subtract](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/subtract)
|
||||
/// See [MDN Temporal.PlainYearMonth.prototype.subtract()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/subtract)
|
||||
pub fn subtract(self: PlainYearMonth, duration: Duration) !PlainYearMonth {
|
||||
const overflow = abi.c.ArithmeticOverflow_Constrain;
|
||||
return wrapPlainYearMonth(abi.c.temporal_rs_PlainYearMonth_subtract(self._inner, duration._inner, overflow));
|
||||
}
|
||||
|
||||
/// Returns the duration from this PlainYearMonth to another.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.until](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/until)
|
||||
/// See [MDN Temporal.PlainYearMonth.prototype.until()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/until)
|
||||
pub fn until(self: PlainYearMonth, other: PlainYearMonth, options: DifferenceSettings) !Duration {
|
||||
const settings = abi.to.diffsettings(options);
|
||||
const result = abi.c.temporal_rs_PlainYearMonth_until(self._inner, other._inner, settings);
|
||||
|
|
@ -129,8 +122,7 @@ pub fn until(self: PlainYearMonth, other: PlainYearMonth, options: DifferenceSet
|
|||
}
|
||||
|
||||
/// Returns the duration from another PlainYearMonth to this one.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.since](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/since)
|
||||
/// See [MDN Temporal.PlainYearMonth.prototype.since()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/since)
|
||||
pub fn since(self: PlainYearMonth, other: PlainYearMonth, options: DifferenceSettings) !Duration {
|
||||
const settings = abi.to.diffsettings(options);
|
||||
const result = abi.c.temporal_rs_PlainYearMonth_since(self._inner, other._inner, settings);
|
||||
|
|
@ -140,8 +132,7 @@ pub fn since(self: PlainYearMonth, other: PlainYearMonth, options: DifferenceSet
|
|||
|
||||
// Property accessors
|
||||
/// Returns the calendar identifier used to interpret the internal ISO 8601 date.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.calendarId](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/calendarId)
|
||||
/// See [MDN Temporal.PlainYearMonth.prototype.calendarId](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/calendarId)
|
||||
pub fn calendarId(self: PlainYearMonth, allocator: std.mem.Allocator) ![]u8 {
|
||||
const calendar_ptr = abi.c.temporal_rs_PlainYearMonth_calendar(self._inner) orelse return error.TemporalError;
|
||||
const cal_id_view = abi.c.temporal_rs_Calendar_identifier(calendar_ptr);
|
||||
|
|
@ -149,22 +140,19 @@ pub fn calendarId(self: PlainYearMonth, allocator: std.mem.Allocator) ![]u8 {
|
|||
}
|
||||
|
||||
/// Returns the year of this year-month relative to the calendar's epoch.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.year](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/year)
|
||||
/// See [MDN Temporal.PlainYearMonth.prototype.year](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/year)
|
||||
pub fn year(self: PlainYearMonth) i32 {
|
||||
return abi.c.temporal_rs_PlainYearMonth_year(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the 1-based month index in the year of this year-month.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.month](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/month)
|
||||
/// See [MDN Temporal.PlainYearMonth.prototype.month](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/month)
|
||||
pub fn month(self: PlainYearMonth) u8 {
|
||||
return abi.c.temporal_rs_PlainYearMonth_month(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the calendar-specific string representing the month of this year-month.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.monthCode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/monthCode)
|
||||
/// See [MDN Temporal.PlainYearMonth.prototype.monthCode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/monthCode)
|
||||
pub fn monthCode(self: PlainYearMonth, allocator: std.mem.Allocator) ![]const u8 {
|
||||
var write = abi.DiplomatWrite.init(allocator);
|
||||
defer write.deinit();
|
||||
|
|
@ -174,36 +162,31 @@ pub fn monthCode(self: PlainYearMonth, allocator: std.mem.Allocator) ![]const u8
|
|||
}
|
||||
|
||||
/// Returns the number of days in the month of this year-month.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.daysInMonth](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/daysInMonth)
|
||||
/// See [MDN Temporal.PlainYearMonth.prototype.daysInMonth](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/daysInMonth)
|
||||
pub fn daysInMonth(self: PlainYearMonth) u16 {
|
||||
return abi.c.temporal_rs_PlainYearMonth_days_in_month(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the number of days in the year of this year-month.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.daysInYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/daysInYear)
|
||||
/// See [MDN Temporal.PlainYearMonth.prototype.daysInYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/daysInYear)
|
||||
pub fn daysInYear(self: PlainYearMonth) u16 {
|
||||
return abi.c.temporal_rs_PlainYearMonth_days_in_year(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the number of months in the year of this year-month.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.monthsInYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/monthsInYear)
|
||||
/// See [MDN Temporal.PlainYearMonth.prototype.monthsInYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/monthsInYear)
|
||||
pub fn monthsInYear(self: PlainYearMonth) u16 {
|
||||
return abi.c.temporal_rs_PlainYearMonth_months_in_year(self._inner);
|
||||
}
|
||||
|
||||
/// Returns true if this year-month is in a leap year.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.inLeapYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/inLeapYear)
|
||||
/// See [MDN Temporal.PlainYearMonth.prototype.inLeapYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/inLeapYear)
|
||||
pub fn inLeapYear(self: PlainYearMonth) bool {
|
||||
return abi.c.temporal_rs_PlainYearMonth_in_leap_year(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the calendar-specific era of this year-month, or null if not applicable.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.era](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/era)
|
||||
/// See [MDN Temporal.PlainYearMonth.prototype.era](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/era)
|
||||
pub fn era(self: PlainYearMonth, allocator: std.mem.Allocator) !?[]const u8 {
|
||||
var write = abi.DiplomatWrite.init(allocator);
|
||||
defer write.deinit();
|
||||
|
|
@ -215,8 +198,7 @@ pub fn era(self: PlainYearMonth, allocator: std.mem.Allocator) !?[]const u8 {
|
|||
}
|
||||
|
||||
/// Returns the year of this year-month within the era, or null if not applicable.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.eraYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/eraYear)
|
||||
/// See [MDN Temporal.PlainYearMonth.prototype.eraYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/eraYear)
|
||||
pub fn eraYear(self: PlainYearMonth) ?i32 {
|
||||
const result = abi.c.temporal_rs_PlainYearMonth_era_year(self._inner);
|
||||
if (!result.is_ok) return null;
|
||||
|
|
@ -225,8 +207,7 @@ pub fn eraYear(self: PlainYearMonth) ?i32 {
|
|||
|
||||
// Modification
|
||||
/// Returns a new PlainYearMonth with some fields replaced by new values.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.with](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/with)
|
||||
/// See [MDN Temporal.PlainYearMonth.prototype.with()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/with)
|
||||
pub fn with(self: PlainYearMonth, options: WithOptions) !PlainYearMonth {
|
||||
// Build month_code view
|
||||
const month_code_view = if (options.month_code) |mc|
|
||||
|
|
@ -259,8 +240,7 @@ pub fn with(self: PlainYearMonth, options: WithOptions) !PlainYearMonth {
|
|||
|
||||
// Conversion
|
||||
/// Returns a PlainDate representing this year-month and a supplied day in the same calendar system.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.toPlainDate](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/toPlainDate)
|
||||
/// See [MDN Temporal.PlainYearMonth.prototype.toPlainDate()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/toPlainDate)
|
||||
pub fn toPlainDate(self: PlainYearMonth, day: u8) !PlainDate {
|
||||
const partial_date = abi.c.PartialDate_option{
|
||||
.is_ok = true,
|
||||
|
|
@ -285,8 +265,7 @@ pub fn toPlainDate(self: PlainYearMonth, day: u8) !PlainDate {
|
|||
|
||||
// String conversions
|
||||
/// Returns a string representing this year-month in RFC 9557 format.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.toString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/toString)
|
||||
/// See [MDN Temporal.PlainYearMonth.prototype.toString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/toString)
|
||||
pub fn toString(self: PlainYearMonth, allocator: std.mem.Allocator) ![]u8 {
|
||||
return toStringWithOptions(self, allocator, .{});
|
||||
}
|
||||
|
|
@ -303,27 +282,26 @@ fn toStringWithOptions(self: PlainYearMonth, allocator: std.mem.Allocator, optio
|
|||
}
|
||||
|
||||
/// Returns a JSON string representing this year-month.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.toJSON](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/toJSON)
|
||||
/// See [MDN Temporal.PlainYearMonth.prototype.toJSON()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/toJSON)
|
||||
pub fn toJSON(self: PlainYearMonth, allocator: std.mem.Allocator) ![]u8 {
|
||||
return toString(self, allocator);
|
||||
}
|
||||
|
||||
/// Returns a locale-sensitive string representing this year-month.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.toLocaleString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/toLocaleString)
|
||||
/// See [MDN Temporal.PlainYearMonth.prototype.toLocaleString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/toLocaleString)
|
||||
pub fn toLocaleString(self: PlainYearMonth, allocator: std.mem.Allocator) ![]u8 {
|
||||
return toString(self, allocator);
|
||||
}
|
||||
|
||||
/// Throws a TypeError, as PlainYearMonth objects cannot be converted to primitive values.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth.valueOf](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth/valueOf)
|
||||
/// See [MDN Temporal.PlainYearMonth.prototype.valueOf()](https://developer.mozilla
|
||||
pub fn valueOf(self: PlainYearMonth) !void {
|
||||
_ = self;
|
||||
return error.ValueError;
|
||||
}
|
||||
|
||||
// ---------- Tests ---------------------
|
||||
|
||||
test init {
|
||||
const ym = try init(2024, 12, null);
|
||||
try std.testing.expectEqual(@as(i32, 2024), ym.year());
|
||||
|
|
|
|||
|
|
@ -1,68 +0,0 @@
|
|||
const builtin = @import("builtin");
|
||||
const std = @import("std");
|
||||
|
||||
const ZonedDateTime = @import("ZonedDateTime.zig");
|
||||
|
||||
const zoneinfo_marker = "zoneinfo/";
|
||||
|
||||
/// Returns the host environment's current time zone identifier.
|
||||
///
|
||||
/// Resolution order:
|
||||
/// 1. `TZ` environment variable (when set and non-empty)
|
||||
/// 2. Unix: `/etc/localtime` symlink target under `zoneinfo/`
|
||||
/// 3. `"UTC"`
|
||||
///
|
||||
/// The caller owns the returned slice.
|
||||
pub fn identifier(allocator: std.mem.Allocator, io: std.Io) ![]const u8 {
|
||||
if (tzFromEnv(allocator)) |tz| return tz;
|
||||
|
||||
if (detectFromPlatform(allocator, io)) |tz| return tz;
|
||||
|
||||
return try allocator.dupe(u8, "UTC");
|
||||
}
|
||||
|
||||
/// Returns a `TimeZone` for the host environment's current time zone.
|
||||
pub fn timeZone(allocator: std.mem.Allocator, io: std.Io) !ZonedDateTime.TimeZone {
|
||||
const id = try identifier(allocator, io);
|
||||
defer allocator.free(id);
|
||||
return ZonedDateTime.TimeZone.init(id);
|
||||
}
|
||||
|
||||
fn tzFromEnv(allocator: std.mem.Allocator) ?[]const u8 {
|
||||
if (!builtin.link_libc) return null;
|
||||
|
||||
const value = std.c.getenv("TZ") orelse return null;
|
||||
const tz = std.mem.span(value);
|
||||
if (tz.len == 0) return null;
|
||||
|
||||
return allocator.dupe(u8, tz) catch null;
|
||||
}
|
||||
|
||||
fn detectFromPlatform(allocator: std.mem.Allocator, io: std.Io) ?[]const u8 {
|
||||
return switch (builtin.os.tag) {
|
||||
.linux, .macos, .freebsd, .openbsd, .netbsd, .dragonfly => detectFromEtcLocaltime(allocator, io) catch null,
|
||||
else => null,
|
||||
};
|
||||
}
|
||||
|
||||
fn detectFromEtcLocaltime(allocator: std.mem.Allocator, io: std.Io) ![]const u8 {
|
||||
var target_buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||
const len = std.Io.Dir.readLinkAbsolute(io, "/etc/localtime", &target_buf) catch return error.NotFound;
|
||||
const target = target_buf[0..len];
|
||||
|
||||
const idx = std.mem.lastIndexOf(u8, target, zoneinfo_marker) orelse return error.NotFound;
|
||||
return try allocator.dupe(u8, target[idx + zoneinfo_marker.len ..]);
|
||||
}
|
||||
|
||||
test identifier {
|
||||
const io = std.testing.io;
|
||||
const tz = try identifier(std.testing.allocator, io);
|
||||
defer std.testing.allocator.free(tz);
|
||||
try std.testing.expect(tz.len > 0);
|
||||
_ = try ZonedDateTime.TimeZone.init(tz);
|
||||
}
|
||||
|
||||
test timeZone {
|
||||
const io = std.testing.io;
|
||||
_ = try timeZone(std.testing.allocator, io);
|
||||
}
|
||||
|
|
@ -13,21 +13,27 @@ const ZonedDateTime = @This();
|
|||
_inner: *abi.c.ZonedDateTime,
|
||||
|
||||
/// The unit of time used for rounding and difference calculations.
|
||||
/// See [MDN Temporal.ZonedDateTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime) for details.
|
||||
pub const Unit = t.Unit;
|
||||
|
||||
/// The rounding mode used for rounding operations.
|
||||
/// See [MDN Temporal.ZonedDateTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime) for details.
|
||||
pub const RoundingMode = t.RoundingMode;
|
||||
|
||||
/// The sign of a duration or difference.
|
||||
/// See [MDN Temporal.ZonedDateTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime) for details.
|
||||
pub const Sign = t.Sign;
|
||||
|
||||
/// Options for difference calculations between ZonedDateTime instances.
|
||||
/// See [MDN Temporal.ZonedDateTime#instance_methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime#instance_methods) for details.
|
||||
pub const DifferenceSettings = t.DifferenceSettings;
|
||||
|
||||
/// Options for rounding ZonedDateTime instances.
|
||||
/// See [MDN Temporal.ZonedDateTime#instance_methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime#instance_methods) for details.
|
||||
pub const RoundOptions = t.RoundingOptions;
|
||||
|
||||
/// Represents a time zone, identified by an IANA time zone identifier or a fixed offset.
|
||||
/// See [MDN Temporal.ZonedDateTime#time-zones-and-offsets](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime#time-zones-and-offsets).
|
||||
pub const TimeZone = struct {
|
||||
_inner: abi.c.TimeZone,
|
||||
|
||||
|
|
@ -41,6 +47,7 @@ pub const TimeZone = struct {
|
|||
};
|
||||
|
||||
/// Disambiguation options for resolving ambiguous local times (e.g., during DST transitions).
|
||||
/// See [MDN Temporal.ZonedDateTime#ambiguity-and-gaps-from-local-time-to-utc-time](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime#ambiguity-and-gaps-from-local-time-to-utc-time).
|
||||
pub const Disambiguation = enum {
|
||||
compatible,
|
||||
earlier,
|
||||
|
|
@ -49,6 +56,7 @@ pub const Disambiguation = enum {
|
|||
};
|
||||
|
||||
/// Options for resolving offset ambiguity when parsing ZonedDateTime from a string.
|
||||
/// See [MDN Temporal.ZonedDateTime#offset-ambiguity](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime#offset-ambiguity).
|
||||
pub const OffsetDisambiguation = enum {
|
||||
use_offset,
|
||||
prefer_offset,
|
||||
|
|
@ -57,6 +65,7 @@ pub const OffsetDisambiguation = enum {
|
|||
};
|
||||
|
||||
/// Controls how the calendar is displayed in string output.
|
||||
/// See [MDN Temporal.ZonedDateTime#rfc-9557-format](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime#rfc-9557-format).
|
||||
pub const CalendarDisplay = enum {
|
||||
auto,
|
||||
always,
|
||||
|
|
@ -65,12 +74,14 @@ pub const CalendarDisplay = enum {
|
|||
};
|
||||
|
||||
/// Controls how the offset is displayed in string output.
|
||||
/// See [MDN Temporal.ZonedDateTime#rfc-9557-format](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime#rfc-9557-format).
|
||||
pub const DisplayOffset = enum {
|
||||
auto,
|
||||
never,
|
||||
};
|
||||
|
||||
/// Controls how the time zone is displayed in string output.
|
||||
/// See [MDN Temporal.ZonedDateTime#rfc-9557-format](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime#rfc-9557-format).
|
||||
pub const DisplayTimeZone = enum {
|
||||
auto,
|
||||
never,
|
||||
|
|
@ -78,8 +89,7 @@ pub const DisplayTimeZone = enum {
|
|||
};
|
||||
|
||||
/// Options for formatting ZonedDateTime as a string.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.toString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toString#parameters)
|
||||
/// See [MDN Temporal.ZonedDateTime#rfc-9557-format](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime#rfc-9557-format).
|
||||
pub const ToStringOptions = struct {
|
||||
fractional_second_digits: ?u8 = null,
|
||||
smallest_unit: ?Unit = null,
|
||||
|
|
@ -90,8 +100,6 @@ pub const ToStringOptions = struct {
|
|||
};
|
||||
|
||||
/// Options for `with()` method.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.with](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/with#parameters)
|
||||
pub const WithOptions = struct {
|
||||
year: ?i32 = null,
|
||||
month: ?u8 = null,
|
||||
|
|
@ -109,29 +117,35 @@ pub const WithOptions = struct {
|
|||
time_zone: ?TimeZone = null,
|
||||
};
|
||||
|
||||
/// Helper function to wrap a C API result into a ZonedDateTime
|
||||
fn wrapZonedDateTime(result: anytype) !ZonedDateTime {
|
||||
const ptr = (try abi.extractResult(result)) orelse return abi.TemporalError.Generic;
|
||||
return .{ ._inner = ptr };
|
||||
}
|
||||
|
||||
/// Creates a new ZonedDateTime from the given epoch nanoseconds and time zone.
|
||||
/// Equivalent to the Temporal.ZonedDateTime constructor.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/ZonedDateTime)
|
||||
/// See [MDN Temporal.ZonedDateTime() constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/ZonedDateTime)
|
||||
pub fn init(epoch_ns: i128, time_zone: TimeZone) !ZonedDateTime {
|
||||
const ns_parts = abi.toI128Nanoseconds(epoch_ns);
|
||||
return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_from_epoch_nanoseconds(ns_parts, abi.to.toTimeZone(time_zone)));
|
||||
}
|
||||
|
||||
/// Creates a new ZonedDateTime from the given epoch milliseconds and time zone.
|
||||
/// See [MDN Temporal.ZonedDateTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime)
|
||||
pub fn fromEpochMilliseconds(epoch_ms: i64, time_zone: TimeZone) !ZonedDateTime {
|
||||
return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_from_epoch_milliseconds(epoch_ms, abi.to.toTimeZone(time_zone)));
|
||||
}
|
||||
|
||||
/// Creates a new ZonedDateTime from the given epoch nanoseconds and time zone.
|
||||
/// See [MDN Temporal.ZonedDateTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime)
|
||||
pub fn fromEpochNanoseconds(epoch_ns: i128, time_zone: TimeZone) !ZonedDateTime {
|
||||
const ns_parts = abi.toI128Nanoseconds(epoch_ns);
|
||||
return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_from_epoch_nanoseconds(ns_parts, abi.to.toTimeZone(time_zone)));
|
||||
}
|
||||
|
||||
/// Parses a ZonedDateTime from a string, with optional disambiguation and offset options.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.from](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/from)
|
||||
/// See [MDN Temporal.ZonedDateTime.from()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/from)
|
||||
pub fn from(s: []const u8, time_zone: ?TimeZone, disambiguation: Disambiguation, offset_disambiguation: OffsetDisambiguation) !ZonedDateTime {
|
||||
_ = time_zone; // The time zone is parsed from the string
|
||||
const view = abi.toDiplomatStringView(s);
|
||||
|
|
@ -140,30 +154,26 @@ pub fn from(s: []const u8, time_zone: ?TimeZone, disambiguation: Disambiguation,
|
|||
|
||||
/// Compares two ZonedDateTime instances by their instant values.
|
||||
/// Returns -1, 0, or 1 if the first is before, equal, or after the second.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.compare](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/compare)
|
||||
/// See [MDN Temporal.ZonedDateTime.compare()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/compare)
|
||||
pub fn compare(a: ZonedDateTime, b: ZonedDateTime) i8 {
|
||||
return abi.c.temporal_rs_ZonedDateTime_compare_instant(a._inner, b._inner);
|
||||
}
|
||||
|
||||
/// Returns a new ZonedDateTime moved forward by the given duration.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.add](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/add)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.add()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/add)
|
||||
pub fn add(self: ZonedDateTime, duration: Duration) !ZonedDateTime {
|
||||
const overflow_opt = abi.toOption(abi.c.ArithmeticOverflow_option, null);
|
||||
return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_add(self._inner, duration._inner, overflow_opt));
|
||||
}
|
||||
|
||||
/// Returns true if this ZonedDateTime is equal to another (same instant, time zone, and calendar).
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.equals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/equals)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.equals()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/equals)
|
||||
pub fn equals(self: ZonedDateTime, other: ZonedDateTime) bool {
|
||||
return abi.c.temporal_rs_ZonedDateTime_equals(self._inner, other._inner);
|
||||
}
|
||||
|
||||
/// Returns the first instant after or before this instant at which the time zone's UTC offset changes, or null if none.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.getTimeZoneTransition](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/getTimeZoneTransition)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.getTimeZoneTransition()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/getTimeZoneTransition)
|
||||
pub fn getTimeZoneTransition(self: ZonedDateTime, direction: enum { next, previous }) !?ZonedDateTime {
|
||||
const dir = switch (direction) {
|
||||
.next => abi.c.TransitionDirection_Next,
|
||||
|
|
@ -178,15 +188,13 @@ pub fn getTimeZoneTransition(self: ZonedDateTime, direction: enum { next, previo
|
|||
}
|
||||
|
||||
/// Returns a new ZonedDateTime rounded to the given unit and options.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.round](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/round)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.round()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/round)
|
||||
pub fn round(self: ZonedDateTime, options: RoundOptions) !ZonedDateTime {
|
||||
return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_round(self._inner, abi.to.roundingOpts(options)));
|
||||
}
|
||||
|
||||
/// Returns the duration from another ZonedDateTime to this one.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.since](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/since)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.since()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/since)
|
||||
pub fn since(self: ZonedDateTime, other: ZonedDateTime, settings: DifferenceSettings) !Duration {
|
||||
const ptr = try abi.extractResult(abi.c.temporal_rs_ZonedDateTime_since(self._inner, other._inner, abi.to.diffsettings(settings)));
|
||||
if (ptr == null) return error.TemporalError;
|
||||
|
|
@ -194,69 +202,60 @@ pub fn since(self: ZonedDateTime, other: ZonedDateTime, settings: DifferenceSett
|
|||
}
|
||||
|
||||
/// Returns a ZonedDateTime representing the start of the day in the time zone.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.startOfDay](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/startOfDay)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.startOfDay()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/startOfDay)
|
||||
pub fn startOfDay(self: ZonedDateTime) !ZonedDateTime {
|
||||
return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_start_of_day(self._inner));
|
||||
}
|
||||
|
||||
/// Returns a new ZonedDateTime moved backward by the given duration.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.subtract](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/subtract)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.subtract()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/subtract)
|
||||
pub fn subtract(self: ZonedDateTime, duration: Duration) !ZonedDateTime {
|
||||
const overflow_opt = abi.toOption(abi.c.ArithmeticOverflow_option, null);
|
||||
return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_subtract(self._inner, duration._inner, overflow_opt));
|
||||
}
|
||||
|
||||
/// Returns a new Instant representing the same instant as this ZonedDateTime.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.toInstant](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toInstant)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.toInstant()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toInstant)
|
||||
pub fn toInstant(self: ZonedDateTime) !Instant {
|
||||
const instant_ptr = abi.c.temporal_rs_ZonedDateTime_to_instant(self._inner) orelse return error.TemporalError;
|
||||
return .{ ._inner = instant_ptr };
|
||||
}
|
||||
|
||||
/// Returns a string representing this ZonedDateTime in RFC 9557 format (ISO 8601 with time zone).
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.toJSON](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toJSON)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.toJSON()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toJSON)
|
||||
pub fn toJSON(self: ZonedDateTime, allocator: std.mem.Allocator) ![]u8 {
|
||||
return self.toString(allocator, .{});
|
||||
}
|
||||
|
||||
/// Returns a language-sensitive string representation of this ZonedDateTime.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.toLocaleString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toLocaleString)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.toLocaleString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toLocaleString)
|
||||
pub fn toLocaleString(self: ZonedDateTime, allocator: std.mem.Allocator) ![]u8 {
|
||||
return self.toString(allocator, .{});
|
||||
}
|
||||
|
||||
/// Returns a PlainDate representing the date portion of this ZonedDateTime.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.toPlainDate](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toPlainDate)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.toPlainDate()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toPlainDate)
|
||||
pub fn toPlainDate(self: ZonedDateTime) !PlainDate {
|
||||
const ptr = abi.c.temporal_rs_ZonedDateTime_to_plain_date(self._inner) orelse return error.TemporalError;
|
||||
return .{ ._inner = ptr };
|
||||
}
|
||||
|
||||
/// Returns a PlainDateTime representing the date and time portions of this ZonedDateTime.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.toPlainDateTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toPlainDateTime)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.toPlainDateTime()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toPlainDateTime)
|
||||
pub fn toPlainDateTime(self: ZonedDateTime) !PlainDateTime {
|
||||
const ptr = abi.c.temporal_rs_ZonedDateTime_to_plain_datetime(self._inner) orelse return error.TemporalError;
|
||||
return .{ ._inner = ptr };
|
||||
}
|
||||
|
||||
/// Returns a PlainTime representing the time portion of this ZonedDateTime.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.toPlainTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toPlainTime)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.toPlainTime()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toPlainTime)
|
||||
pub fn toPlainTime(self: ZonedDateTime) !PlainTime {
|
||||
const ptr = abi.c.temporal_rs_ZonedDateTime_to_plain_time(self._inner) orelse return error.TemporalError;
|
||||
return .{ ._inner = ptr };
|
||||
}
|
||||
|
||||
/// Returns a string representing this ZonedDateTime in RFC 9557 format, with options for formatting.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.toString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toString)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.toString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/toString)
|
||||
pub fn toString(self: ZonedDateTime, allocator: std.mem.Allocator, opts: ToStringOptions) ![]u8 {
|
||||
var write = abi.DiplomatWrite.init(allocator);
|
||||
defer write.deinit();
|
||||
|
|
@ -275,8 +274,7 @@ pub fn toString(self: ZonedDateTime, allocator: std.mem.Allocator, opts: ToStrin
|
|||
}
|
||||
|
||||
/// Returns the duration from this ZonedDateTime to another.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.until](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/until)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.until()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/until)
|
||||
pub fn until(self: ZonedDateTime, other: ZonedDateTime, settings: DifferenceSettings) !Duration {
|
||||
const ptr = try abi.extractResult(abi.c.temporal_rs_ZonedDateTime_until(self._inner, other._inner, abi.to.diffsettings(settings)));
|
||||
if (ptr == null) return error.TemporalError;
|
||||
|
|
@ -284,8 +282,7 @@ pub fn until(self: ZonedDateTime, other: ZonedDateTime, settings: DifferenceSett
|
|||
}
|
||||
|
||||
/// Throws an error; valueOf() is not supported for ZonedDateTime.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.valueOf](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/valueOf)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.valueOf()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/valueOf)
|
||||
pub fn valueOf(_: ZonedDateTime) !void {
|
||||
return error.ValueOfNotSupported;
|
||||
}
|
||||
|
|
@ -312,8 +309,7 @@ pub fn with(self: ZonedDateTime, allocator: std.mem.Allocator, fields: anytype)
|
|||
}
|
||||
|
||||
/// Returns a new ZonedDateTime interpreted in the new calendar system.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.withCalendar](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/withCalendar)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.withCalendar()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/withCalendar)
|
||||
pub fn withCalendar(self: ZonedDateTime, calendar: []const u8) !ZonedDateTime {
|
||||
const cal_view = abi.toDiplomatStringView(calendar);
|
||||
const cal_result = abi.c.temporal_rs_AnyCalendarKind_parse_temporal_calendar_string(cal_view);
|
||||
|
|
@ -324,24 +320,21 @@ pub fn withCalendar(self: ZonedDateTime, calendar: []const u8) !ZonedDateTime {
|
|||
}
|
||||
|
||||
/// Returns a new ZonedDateTime with the time part replaced by the new time.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.withPlainTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/withPlainTime)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.withPlainTime()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/withPlainTime)
|
||||
pub fn withPlainTime(self: ZonedDateTime, time: ?PlainTime) !ZonedDateTime {
|
||||
const time_ptr = if (time) |tt| tt._inner else null;
|
||||
return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_with_plain_time(self._inner, time_ptr));
|
||||
}
|
||||
|
||||
/// Returns a new ZonedDateTime representing the same instant in a new time zone.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.withTimeZone](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/withTimeZone)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.withTimeZone()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/withTimeZone)
|
||||
pub fn withTimeZone(self: ZonedDateTime, time_zone: TimeZone) !ZonedDateTime {
|
||||
return wrapZonedDateTime(abi.c.temporal_rs_ZonedDateTime_with_timezone(self._inner, abi.to.toTimeZone(time_zone)));
|
||||
}
|
||||
|
||||
// Property accessors
|
||||
/// Returns the calendar identifier used to interpret the internal ISO 8601 date.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.calendarId](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/calendarId)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.calendarId](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/calendarId)
|
||||
pub fn calendarId(self: ZonedDateTime, allocator: std.mem.Allocator) ![]u8 {
|
||||
const calendar_ptr = abi.c.temporal_rs_ZonedDateTime_calendar(self._inner) orelse return error.TemporalError;
|
||||
const cal_id_view = abi.c.temporal_rs_Calendar_identifier(calendar_ptr);
|
||||
|
|
@ -349,65 +342,56 @@ pub fn calendarId(self: ZonedDateTime, allocator: std.mem.Allocator) ![]u8 {
|
|||
}
|
||||
|
||||
/// Returns the 1-based day index in the month of this date.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.day](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/day)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.day](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/day)
|
||||
pub fn day(self: ZonedDateTime) u8 {
|
||||
return abi.c.temporal_rs_ZonedDateTime_day(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the 1-based day index in the week of this date.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.dayOfWeek](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/dayOfWeek)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.dayOfWeek](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/dayOfWeek)
|
||||
pub fn dayOfWeek(self: ZonedDateTime) u16 {
|
||||
return abi.c.temporal_rs_ZonedDateTime_day_of_week(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the 1-based day index in the year of this date.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.dayOfYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/dayOfYear)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.dayOfYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/dayOfYear)
|
||||
pub fn dayOfYear(self: ZonedDateTime) u16 {
|
||||
return abi.c.temporal_rs_ZonedDateTime_day_of_year(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the number of days in the month of this date.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.daysInMonth](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/daysInMonth)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.daysInMonth](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/daysInMonth)
|
||||
pub fn daysInMonth(self: ZonedDateTime) u16 {
|
||||
return abi.c.temporal_rs_ZonedDateTime_days_in_month(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the number of days in the week of this date.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.daysInWeek](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/daysInWeek)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.daysInWeek](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/daysInWeek)
|
||||
pub fn daysInWeek(self: ZonedDateTime) u16 {
|
||||
return abi.c.temporal_rs_ZonedDateTime_days_in_week(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the number of days in the year of this date.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.daysInYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/daysInYear)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.daysInYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/daysInYear)
|
||||
pub fn daysInYear(self: ZonedDateTime) u16 {
|
||||
return abi.c.temporal_rs_ZonedDateTime_days_in_year(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the number of milliseconds since the Unix epoch to this instant.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.epochMilliseconds](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/epochMilliseconds)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.epochMilliseconds](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/epochMilliseconds)
|
||||
pub fn epochMilliseconds(self: ZonedDateTime) i64 {
|
||||
return abi.c.temporal_rs_ZonedDateTime_epoch_milliseconds(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the number of nanoseconds since the Unix epoch to this instant.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.epochNanoseconds](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/epochNanoseconds)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.epochNanoseconds](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/epochNanoseconds)
|
||||
pub fn epochNanoseconds(self: ZonedDateTime) i128 {
|
||||
const parts = abi.c.temporal_rs_ZonedDateTime_epoch_nanoseconds(self._inner);
|
||||
return abi.fromI128Nanoseconds(parts);
|
||||
}
|
||||
|
||||
/// Returns the calendar-specific era of this date, or null if not applicable.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.era](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/era)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.era](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/era)
|
||||
pub fn era(self: ZonedDateTime, allocator: std.mem.Allocator) !?[]u8 {
|
||||
var write = abi.DiplomatWrite.init(allocator);
|
||||
defer write.deinit();
|
||||
|
|
@ -421,66 +405,57 @@ pub fn era(self: ZonedDateTime, allocator: std.mem.Allocator) !?[]u8 {
|
|||
}
|
||||
|
||||
/// Returns the year of this date within the era, or null if not applicable.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.eraYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/eraYear)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.eraYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/eraYear)
|
||||
pub fn eraYear(self: ZonedDateTime) ?i32 {
|
||||
const result = abi.c.temporal_rs_ZonedDateTime_era_year(self._inner);
|
||||
return abi.fromOption(result);
|
||||
}
|
||||
|
||||
/// Returns the hour component of this time (0-23).
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.hour](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/hour)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.hour](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/hour)
|
||||
pub fn hour(self: ZonedDateTime) u8 {
|
||||
return abi.c.temporal_rs_ZonedDateTime_hour(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the number of hours in the day of this date in the time zone.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.hoursInDay](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/hoursInDay)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.hoursInDay](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/hoursInDay)
|
||||
pub fn hoursInDay(self: ZonedDateTime) !f64 {
|
||||
const result = abi.c.temporal_rs_ZonedDateTime_hours_in_day(self._inner);
|
||||
return try abi.extractResult(result);
|
||||
}
|
||||
|
||||
/// Returns true if this date is in a leap year.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.inLeapYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/inLeapYear)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.inLeapYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/inLeapYear)
|
||||
pub fn inLeapYear(self: ZonedDateTime) bool {
|
||||
return abi.c.temporal_rs_ZonedDateTime_in_leap_year(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the microsecond component of this time (0-999).
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.microsecond](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/microsecond)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.microsecond](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/microsecond)
|
||||
pub fn microsecond(self: ZonedDateTime) u16 {
|
||||
return abi.c.temporal_rs_ZonedDateTime_microsecond(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the millisecond component of this time (0-999).
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.millisecond](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/millisecond)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.millisecond](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/millisecond)
|
||||
pub fn millisecond(self: ZonedDateTime) u16 {
|
||||
return abi.c.temporal_rs_ZonedDateTime_millisecond(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the minute component of this time (0-59).
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.minute](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/minute)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.minute](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/minute)
|
||||
pub fn minute(self: ZonedDateTime) u8 {
|
||||
return abi.c.temporal_rs_ZonedDateTime_minute(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the 1-based month index in the year of this date.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.month](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/month)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.month](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/month)
|
||||
pub fn month(self: ZonedDateTime) u8 {
|
||||
return abi.c.temporal_rs_ZonedDateTime_month(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the calendar-specific string representing the month of this date.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.monthCode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/monthCode)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.monthCode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/monthCode)
|
||||
pub fn monthCode(self: ZonedDateTime, allocator: std.mem.Allocator) ![]u8 {
|
||||
var write = abi.DiplomatWrite.init(allocator);
|
||||
defer write.deinit();
|
||||
|
|
@ -489,22 +464,19 @@ pub fn monthCode(self: ZonedDateTime, allocator: std.mem.Allocator) ![]u8 {
|
|||
}
|
||||
|
||||
/// Returns the number of months in the year of this date.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.monthsInYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/monthsInYear)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.monthsInYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/monthsInYear)
|
||||
pub fn monthsInYear(self: ZonedDateTime) u16 {
|
||||
return abi.c.temporal_rs_ZonedDateTime_months_in_year(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the nanosecond component of this time (0-999).
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.nanosecond](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/nanosecond)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.nanosecond](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/nanosecond)
|
||||
pub fn nanosecond(self: ZonedDateTime) u16 {
|
||||
return abi.c.temporal_rs_ZonedDateTime_nanosecond(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the offset used to interpret the internal instant, as a string (±HH:mm).
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.offset](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/offset)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.offset](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/offset)
|
||||
pub fn offset(self: ZonedDateTime, allocator: std.mem.Allocator) ![]u8 {
|
||||
var write = abi.DiplomatWrite.init(allocator);
|
||||
defer write.deinit();
|
||||
|
|
@ -514,22 +486,19 @@ pub fn offset(self: ZonedDateTime, allocator: std.mem.Allocator) ![]u8 {
|
|||
}
|
||||
|
||||
/// Returns the offset used to interpret the internal instant, as a number of nanoseconds.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.offsetNanoseconds](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/offsetNanoseconds)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.offsetNanoseconds](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/offsetNanoseconds)
|
||||
pub fn offsetNanoseconds(self: ZonedDateTime) i64 {
|
||||
return abi.c.temporal_rs_ZonedDateTime_offset_nanoseconds(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the second component of this time (0-59).
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.second](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/second)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.second](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/second)
|
||||
pub fn second(self: ZonedDateTime) u8 {
|
||||
return abi.c.temporal_rs_ZonedDateTime_second(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the time zone identifier used to interpret the internal instant.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.timeZoneId](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/timeZoneId)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.timeZoneId](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/timeZoneId)
|
||||
pub fn timeZoneId(self: ZonedDateTime, allocator: std.mem.Allocator) ![]u8 {
|
||||
const tz = abi.c.temporal_rs_ZonedDateTime_timezone(self._inner);
|
||||
var write = abi.DiplomatWrite.init(allocator);
|
||||
|
|
@ -541,23 +510,20 @@ pub fn timeZoneId(self: ZonedDateTime, allocator: std.mem.Allocator) ![]u8 {
|
|||
}
|
||||
|
||||
/// Returns the 1-based week index in the year of this date, or null if not defined.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.weekOfYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/weekOfYear)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.weekOfYear](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/weekOfYear)
|
||||
pub fn weekOfYear(self: ZonedDateTime) ?u8 {
|
||||
const result = abi.c.temporal_rs_ZonedDateTime_week_of_year(self._inner);
|
||||
return abi.fromOption(result);
|
||||
}
|
||||
|
||||
/// Returns the year of this date relative to the calendar's epoch.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.year](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/year)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.year](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/year)
|
||||
pub fn year(self: ZonedDateTime) i32 {
|
||||
return abi.c.temporal_rs_ZonedDateTime_year(self._inner);
|
||||
}
|
||||
|
||||
/// Returns the year to be paired with the weekOfYear of this date, or null if not defined.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime.yearOfWeek](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/yearOfWeek)
|
||||
/// See [MDN Temporal.ZonedDateTime.prototype.yearOfWeek](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime/yearOfWeek)
|
||||
pub fn yearOfWeek(self: ZonedDateTime) ?i32 {
|
||||
const result = abi.c.temporal_rs_ZonedDateTime_year_of_week(self._inner);
|
||||
return abi.fromOption(result);
|
||||
|
|
@ -574,12 +540,7 @@ pub fn deinit(self: ZonedDateTime) void {
|
|||
abi.c.temporal_rs_ZonedDateTime_destroy(self._inner);
|
||||
}
|
||||
|
||||
/// Helper function to wrap a C API result into a ZonedDateTime
|
||||
fn wrapZonedDateTime(result: anytype) !ZonedDateTime {
|
||||
const ptr = (try abi.extractResult(result)) orelse return abi.TemporalError.Generic;
|
||||
return .{ ._inner = ptr };
|
||||
}
|
||||
|
||||
// ---------- Tests ---------------------
|
||||
test init {
|
||||
const tz = try TimeZone.init("America/New_York");
|
||||
const zdt = try init(0, tz);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub const c = @import("libtemporal").c;
|
||||
pub const c = @import("temporal_rs").c;
|
||||
|
||||
pub const to_string_rounding_options_auto: c.ToStringRoundingOptions = .{
|
||||
.precision = .{ .is_minute = false, .precision = toOption(c.OptionU8, null) },
|
||||
|
|
|
|||
40
src/root.zig
40
src/root.zig
|
|
@ -4,49 +4,49 @@ const Temporal = @This();
|
|||
/// The `Temporal.Duration` object represents a difference between two time points, which can be used in date/time arithmetic.
|
||||
/// It is fundamentally represented as a combination of years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, and nanoseconds values.
|
||||
///
|
||||
/// See: [Temporal.Duration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration)
|
||||
/// - [MDN Temporal.Duration](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Duration)
|
||||
pub const Duration = @import("Duration.zig");
|
||||
|
||||
/// The `Temporal.Instant` object represents a unique point in time, with nanosecond precision.
|
||||
/// It is fundamentally represented as the number of nanoseconds since the Unix epoch (midnight at the beginning of January 1, 1970, UTC), without any time zone or calendar system.
|
||||
///
|
||||
/// See: [Temporal.Instant](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant)
|
||||
/// - [MDN Temporal.Instant](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Instant)
|
||||
pub const Instant = @import("Instant.zig");
|
||||
|
||||
/// The `Temporal.Now` namespace object contains static methods for getting the current time in various formats.
|
||||
/// All properties and methods are static.
|
||||
///
|
||||
/// See: [Temporal.Now](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Now)
|
||||
/// - [MDN Temporal.Now](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/Now)
|
||||
pub const Now = @import("Now.zig");
|
||||
|
||||
/// The `Temporal.PlainDate` object represents a calendar date (year, month, day) with no time or time zone.
|
||||
///
|
||||
/// See: [Temporal.PlainDate](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainDate)
|
||||
/// - [MDN Temporal.PlainDate](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainDate)
|
||||
pub const PlainDate = @import("PlainDate.zig");
|
||||
|
||||
/// The `Temporal.PlainDateTime` object represents a calendar date and wall-clock time, but no time zone or offset.
|
||||
///
|
||||
/// See: [Temporal.PlainDateTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainDateTime)
|
||||
/// - [MDN Temporal.PlainDateTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainDateTime)
|
||||
pub const PlainDateTime = @import("PlainDateTime.zig");
|
||||
|
||||
/// The `Temporal.PlainMonthDay` object represents a month and day in a calendar, with no year or time.
|
||||
///
|
||||
/// See: [Temporal.PlainMonthDay](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay)
|
||||
/// - [MDN Temporal.PlainMonthDay](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainMonthDay)
|
||||
pub const PlainMonthDay = @import("PlainMonthDay.zig");
|
||||
|
||||
/// The `Temporal.PlainTime` object represents a wall-clock time, with no date or time zone.
|
||||
///
|
||||
/// See: [Temporal.PlainTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime)
|
||||
/// - [MDN Temporal.PlainTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainTime)
|
||||
pub const PlainTime = @import("PlainTime.zig");
|
||||
|
||||
/// The `Temporal.PlainYearMonth` object represents a particular month in a specific year, with no day or time.
|
||||
///
|
||||
/// See: [Temporal.PlainYearMonth](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth)
|
||||
/// - [MDN Temporal.PlainYearMonth](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/PlainYearMonth)
|
||||
pub const PlainYearMonth = @import("PlainYearMonth.zig");
|
||||
|
||||
/// The `Temporal.ZonedDateTime` object represents an exact time, including a time zone and calendar.
|
||||
///
|
||||
/// See: [Temporal.ZonedDateTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime)
|
||||
/// - [MDN Temporal.ZonedDateTime](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal/ZonedDateTime)
|
||||
pub const ZonedDateTime = @import("ZonedDateTime.zig");
|
||||
|
||||
test Temporal {
|
||||
|
|
@ -526,10 +526,10 @@ fn assertDecls(comptime T: type, checks: anytype) !void {
|
|||
var hasField = false;
|
||||
if (typeInfo == .@"struct") {
|
||||
const struct_info = typeInfo.@"struct";
|
||||
inline for (struct_info.field_names) |field_name| {
|
||||
inline for (struct_info.fields) |field| {
|
||||
// Check both camelCase and snake_case
|
||||
if (std.mem.eql(u8, field_name, check) or
|
||||
std.mem.eql(u8, field_name, camelToSnakeCase(check)))
|
||||
if (std.mem.eql(u8, field.name, check) or
|
||||
std.mem.eql(u8, field.name, camelToSnakeCase(check)))
|
||||
{
|
||||
hasField = true;
|
||||
break;
|
||||
|
|
@ -548,39 +548,39 @@ fn assertDecls(comptime T: type, checks: anytype) !void {
|
|||
const struct_info = typeInfo.@"struct";
|
||||
|
||||
// Check declarations
|
||||
inline for (struct_info.decl_names) |decl_name| {
|
||||
inline for (struct_info.decls) |decl| {
|
||||
// Allow deinit as extraneous
|
||||
if (comptime std.mem.eql(u8, decl_name, "deinit")) continue;
|
||||
if (comptime std.mem.eql(u8, decl.name, "deinit")) continue;
|
||||
|
||||
var found = false;
|
||||
inline for (checks) |check| {
|
||||
if (std.mem.eql(u8, decl_name, check)) {
|
||||
if (std.mem.eql(u8, decl.name, check)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
std.log.err("Extraneous {s} decl: {s}", .{ @typeName(T), decl_name });
|
||||
std.log.err("Extraneous {s} decl: {s}", .{ @typeName(T), decl.name });
|
||||
try std.testing.expect(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Check fields (properties)
|
||||
inline for (struct_info.field_names) |field_name| {
|
||||
inline for (struct_info.fields) |field| {
|
||||
// Allow internal fields (starting with underscore)
|
||||
if (comptime std.mem.startsWith(u8, field_name, "_")) continue;
|
||||
if (comptime std.mem.startsWith(u8, field.name, "_")) continue;
|
||||
|
||||
var found = false;
|
||||
inline for (checks) |check| {
|
||||
if (std.mem.eql(u8, field_name, camelToSnakeCase(check))) {
|
||||
if (std.mem.eql(u8, field.name, camelToSnakeCase(check))) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
std.log.err("Extraneous {s} field: {s}", .{ @typeName(T), field_name });
|
||||
std.log.err("Extraneous {s} field: {s}", .{ @typeName(T), field.name });
|
||||
try std.testing.expect(false);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,11 @@
|
|||
/// # Temporal Types and Utilities
|
||||
///
|
||||
/// This file defines core types and options used throughout the Temporal API implementation.
|
||||
///
|
||||
/// - [MDN Temporal](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal)
|
||||
/// ## Unit
|
||||
/// Time unit for Temporal operations (e.g., nanosecond, second, day, year).
|
||||
/// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal
|
||||
pub const Unit = enum {
|
||||
auto,
|
||||
nanosecond,
|
||||
|
|
|
|||
|
|
@ -100,13 +100,13 @@ pub fn main(init: std.process.Init) !void {
|
|||
|
||||
while (attempt < max_attempts) : (attempt += 1) {
|
||||
current_test = friendly_name;
|
||||
std.testing.allocator_instance = .init(std.heap.page_allocator, .{});
|
||||
std.testing.allocator_instance = .{};
|
||||
final_result = t.func();
|
||||
current_test = null;
|
||||
|
||||
final_ns_taken = slowest.endTiming(allocator, scope_name, friendly_name);
|
||||
|
||||
if (std.testing.allocator_instance.deinit() > 0) {
|
||||
if (std.testing.allocator_instance.deinit() == .leak) {
|
||||
leak += 1;
|
||||
Printer.status(.fail, "\n{s}\n\"{s}\" - Memory Leak\n{s}\n", .{ BORDER, friendly_name, BORDER });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
import { readFile } from "fs/promises";
|
||||
|
||||
let memory = null;
|
||||
|
||||
const buffer = await readFile("zig-out/bin/temporalz.wasm");
|
||||
const temporalz = await WebAssembly.instantiate(buffer, {
|
||||
env: {
|
||||
console(ptr, len) {
|
||||
const bytes = new Uint8Array(memory.buffer, ptr, len);
|
||||
const message = new TextDecoder().decode(bytes);
|
||||
console.log(message);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
memory = temporalz.instance.exports.memory;
|
||||
temporalz.instance.exports._start();
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const program = @import("root.zig");
|
||||
|
||||
const freestanding = builtin.os.tag == .freestanding;
|
||||
|
||||
pub fn main(init: Init) !void {
|
||||
const allocator = std.heap.page_allocator;
|
||||
const io = if (freestanding) null else init.io;
|
||||
|
||||
try program.run(allocator, io);
|
||||
}
|
||||
|
||||
// -- //
|
||||
const Init = if (freestanding) std.process.Init.Minimal else std.process.Init;
|
||||
pub const std_options: std.Options = .{
|
||||
.logFn = if (freestanding) logFn else std.log.defaultLog,
|
||||
};
|
||||
|
||||
extern fn console(ptr: [*]u8, len: u32) void;
|
||||
fn logFn(comptime _: anytype, comptime _: anytype, comptime format: []const u8, args: anytype) void {
|
||||
const formatted = std.fmt.allocPrint(std.heap.wasm_allocator, format, args) catch return;
|
||||
console(formatted.ptr, formatted.len);
|
||||
}
|
||||
1
test/temporal-test262-runner
Submodule
1
test/temporal-test262-runner
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 80286aa081b04bb9c9881615af62ae0d47912791
|
||||
683
test/test262/polyfill.js
Normal file
683
test/test262/polyfill.js
Normal file
|
|
@ -0,0 +1,683 @@
|
|||
// This polyfill is executed in a vm.Script context by test262-runner,
|
||||
// so it must be synchronous and self-contained.
|
||||
// The wasm bytes are injected as global.__TEMPORALZ_WASM_BYTES__ by the runner.
|
||||
(function () {
|
||||
if (!globalThis.__TEMPORALZ_WASM_BYTES__) {
|
||||
throw new Error("WASM bytes not injected into test context");
|
||||
}
|
||||
|
||||
const wasmBinary = globalThis.__TEMPORALZ_WASM_BYTES__;
|
||||
const wasmModule = new WebAssembly.Module(wasmBinary);
|
||||
const wasmInstance = new WebAssembly.Instance(wasmModule, {
|
||||
env: {
|
||||
console(ptr, len) {
|
||||
const bytes = new Uint8Array(memory.buffer, ptr, len);
|
||||
globalThis.console.log(decoder.decode(bytes));
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const exports = wasmInstance.exports;
|
||||
const memory = exports.memory;
|
||||
|
||||
const encoder = {
|
||||
encode(str) {
|
||||
const buf = [];
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
const code = str.charCodeAt(i);
|
||||
if (code < 0x80) {
|
||||
buf.push(code);
|
||||
} else if (code < 0x800) {
|
||||
buf.push(0xc0 | (code >> 6), 0x80 | (code & 0x3f));
|
||||
} else if (code < 0xd800 || code >= 0xe000) {
|
||||
buf.push(0xe0 | (code >> 12), 0x80 | ((code >> 6) & 0x3f), 0x80 | (code & 0x3f));
|
||||
} else {
|
||||
const code2 = str.charCodeAt(++i);
|
||||
const codePoint = 0x10000 + (((code & 0x3ff) << 10) | (code2 & 0x3ff));
|
||||
buf.push(
|
||||
0xf0 | (codePoint >> 18),
|
||||
0x80 | ((codePoint >> 12) & 0x3f),
|
||||
0x80 | ((codePoint >> 6) & 0x3f),
|
||||
0x80 | (codePoint & 0x3f)
|
||||
);
|
||||
}
|
||||
}
|
||||
return new Uint8Array(buf);
|
||||
},
|
||||
};
|
||||
|
||||
const decoder = {
|
||||
decode(bytes) {
|
||||
let str = "";
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
const byte = bytes[i];
|
||||
if (byte < 0x80) {
|
||||
str += String.fromCharCode(byte);
|
||||
} else if ((byte & 0xe0) === 0xc0) {
|
||||
str += String.fromCharCode(((byte & 0x1f) << 6) | (bytes[++i] & 0x3f));
|
||||
} else if ((byte & 0xf0) === 0xe0) {
|
||||
str += String.fromCharCode(
|
||||
((byte & 0x0f) << 12) | ((bytes[++i] & 0x3f) << 6) | (bytes[++i] & 0x3f)
|
||||
);
|
||||
} else if ((byte & 0xf8) === 0xf0) {
|
||||
const codePoint =
|
||||
((byte & 0x07) << 18) |
|
||||
((bytes[++i] & 0x3f) << 12) |
|
||||
((bytes[++i] & 0x3f) << 6) |
|
||||
(bytes[++i] & 0x3f);
|
||||
const high = ((codePoint - 0x10000) >> 10) + 0xd800;
|
||||
const low = ((codePoint - 0x10000) & 0x3ff) + 0xdc00;
|
||||
str += String.fromCharCode(high, low);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
},
|
||||
};
|
||||
|
||||
function readString(ptr, len) {
|
||||
return decoder.decode(new Uint8Array(memory.buffer, ptr, len));
|
||||
}
|
||||
|
||||
function lastError() {
|
||||
const ptr = exports.temporalz_last_error_ptr();
|
||||
const len = exports.temporalz_last_error_len();
|
||||
if (!ptr || !len) return new Error("temporalz error");
|
||||
const msg = readString(ptr, len);
|
||||
exports.temporalz_last_error_clear();
|
||||
if (msg.includes("Range")) return new RangeError(msg);
|
||||
if (msg.includes("Type")) return new TypeError(msg);
|
||||
return new Error(msg);
|
||||
}
|
||||
|
||||
function requireHandle(handle) {
|
||||
if (!handle) throw lastError();
|
||||
return handle;
|
||||
}
|
||||
|
||||
function allocString(text) {
|
||||
const bytes = encoder.encode(text);
|
||||
const ptr = exports.temporalz_alloc(bytes.length);
|
||||
if (!ptr) throw lastError();
|
||||
new Uint8Array(memory.buffer, ptr, bytes.length).set(bytes);
|
||||
return { ptr, len: bytes.length };
|
||||
}
|
||||
|
||||
function takeString(packed) {
|
||||
if (!packed) throw lastError();
|
||||
const value = BigInt(packed);
|
||||
const ptr = Number(value >> 32n);
|
||||
const len = Number(value & 0xffffffffn);
|
||||
const text = readString(ptr, len);
|
||||
exports.temporalz_string_free(ptr, len);
|
||||
return text;
|
||||
}
|
||||
|
||||
function splitI128(value) {
|
||||
const v = typeof value === "bigint" ? value : BigInt(value);
|
||||
const mask = (1n << 64n) - 1n;
|
||||
return { hi: v >> 64n, lo: v & mask };
|
||||
}
|
||||
|
||||
function joinI128(hi, lo) {
|
||||
const mask = (1n << 64n) - 1n;
|
||||
return (BigInt(hi) << 64n) | (BigInt(lo) & mask);
|
||||
}
|
||||
|
||||
const unitCodes = {
|
||||
nanosecond: 1,
|
||||
microsecond: 2,
|
||||
millisecond: 3,
|
||||
second: 4,
|
||||
minute: 5,
|
||||
hour: 6,
|
||||
day: 7,
|
||||
week: 8,
|
||||
month: 9,
|
||||
year: 10,
|
||||
auto: 11,
|
||||
};
|
||||
|
||||
const roundingModeCodes = {
|
||||
ceil: 1,
|
||||
floor: 2,
|
||||
expand: 3,
|
||||
trunc: 4,
|
||||
halfCeil: 5,
|
||||
halfFloor: 6,
|
||||
halfExpand: 7,
|
||||
halfTrunc: 8,
|
||||
halfEven: 9,
|
||||
};
|
||||
|
||||
function toUnitCode(value, name) {
|
||||
if (value === undefined || value === null) return 255;
|
||||
const code = unitCodes[value];
|
||||
if (!code) throw new RangeError(`Invalid ${name}`);
|
||||
return code;
|
||||
}
|
||||
|
||||
function toRoundingModeCode(value) {
|
||||
if (value === undefined || value === null) return 255;
|
||||
const code = roundingModeCodes[value];
|
||||
if (!code) throw new RangeError("Invalid roundingMode");
|
||||
return code;
|
||||
}
|
||||
|
||||
function toIntegerBigInt(value, name) {
|
||||
if (typeof value === "bigint") return value;
|
||||
const number = Number(value);
|
||||
if (!isFiniteNumber(number)) throw new RangeError(`${name} must be finite`);
|
||||
if (!Number.isInteger(number)) throw new RangeError(`${name} must be an integer`);
|
||||
return BigInt(number);
|
||||
}
|
||||
|
||||
function toNumber(value, name) {
|
||||
const number = Number(value);
|
||||
if (!isFiniteNumber(number)) throw new RangeError(`${name} must be finite`);
|
||||
return number;
|
||||
}
|
||||
|
||||
function toInteger(value, name) {
|
||||
const number = Number(value);
|
||||
if (!isFiniteNumber(number)) throw new RangeError(`${name} must be finite`);
|
||||
if (!Number.isInteger(number)) throw new RangeError(`${name} must be an integer`);
|
||||
return number;
|
||||
}
|
||||
|
||||
function isFiniteNumber(value) {
|
||||
return value === value && value !== Infinity && value !== -Infinity;
|
||||
}
|
||||
|
||||
function unimplemented(name) {
|
||||
return function () {
|
||||
throw new Error(`${name} is not implemented yet`);
|
||||
};
|
||||
}
|
||||
|
||||
class Instant {
|
||||
constructor(handle) {
|
||||
this._handle = handle;
|
||||
}
|
||||
|
||||
static _fromHandle(handle) {
|
||||
return new Instant(handle);
|
||||
}
|
||||
|
||||
static fromEpochMilliseconds(epochMs) {
|
||||
const number = Number(epochMs);
|
||||
if (!isFiniteNumber(number)) throw new RangeError("epochMilliseconds must be finite");
|
||||
const handle = exports.temporalz_instant_from_epoch_milliseconds(number);
|
||||
return Instant._fromHandle(requireHandle(handle));
|
||||
}
|
||||
|
||||
static fromEpochNanoseconds(epochNs) {
|
||||
const parts = splitI128(epochNs);
|
||||
const handle = exports.temporalz_instant_from_epoch_nanoseconds_parts(
|
||||
parts.hi,
|
||||
parts.lo
|
||||
);
|
||||
return Instant._fromHandle(requireHandle(handle));
|
||||
}
|
||||
|
||||
static from(value) {
|
||||
if (value instanceof Instant) return value;
|
||||
if (typeof value === "string") {
|
||||
const text = allocString(value);
|
||||
const handle = exports.temporalz_instant_from_utf8(text.ptr, text.len);
|
||||
exports.temporalz_free(text.ptr, text.len);
|
||||
return Instant._fromHandle(requireHandle(handle));
|
||||
}
|
||||
if (value && typeof value === "object") {
|
||||
if (value.epochNanoseconds !== undefined) {
|
||||
return Instant.fromEpochNanoseconds(value.epochNanoseconds);
|
||||
}
|
||||
if (value.epochMilliseconds !== undefined) {
|
||||
return Instant.fromEpochMilliseconds(value.epochMilliseconds);
|
||||
}
|
||||
}
|
||||
throw new TypeError("Instant.from expects a string or object");
|
||||
}
|
||||
|
||||
get epochMilliseconds() {
|
||||
return exports.temporalz_instant_epoch_milliseconds(this._handle);
|
||||
}
|
||||
|
||||
get epochNanoseconds() {
|
||||
const hi = exports.temporalz_instant_epoch_nanoseconds_hi(this._handle);
|
||||
const lo = exports.temporalz_instant_epoch_nanoseconds_lo(this._handle);
|
||||
return joinI128(hi, lo);
|
||||
}
|
||||
|
||||
toString() {
|
||||
return takeString(exports.temporalz_instant_to_string(this._handle));
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return this.toString();
|
||||
}
|
||||
|
||||
add(durationLike) {
|
||||
const dur = Duration.from(durationLike);
|
||||
const handle = exports.temporalz_instant_add(this._handle, dur._handle);
|
||||
return Instant._fromHandle(requireHandle(handle));
|
||||
}
|
||||
|
||||
subtract(durationLike) {
|
||||
const dur = Duration.from(durationLike);
|
||||
const handle = exports.temporalz_instant_subtract(this._handle, dur._handle);
|
||||
return Instant._fromHandle(requireHandle(handle));
|
||||
}
|
||||
|
||||
round(options) {
|
||||
if (!options || typeof options !== "object") {
|
||||
throw new TypeError("round options must be an object");
|
||||
}
|
||||
const smallestUnit = toUnitCode(options.smallestUnit, "smallestUnit");
|
||||
if (smallestUnit === 255) throw new RangeError("smallestUnit is required");
|
||||
const roundingMode = toRoundingModeCode(options.roundingMode);
|
||||
|
||||
let roundingIncrement = 0;
|
||||
if (options.roundingIncrement !== undefined) {
|
||||
const inc = Number(options.roundingIncrement);
|
||||
if (!isFiniteNumber(inc) || !Number.isInteger(inc) || inc <= 0) {
|
||||
throw new RangeError("Invalid roundingIncrement");
|
||||
}
|
||||
roundingIncrement = inc;
|
||||
}
|
||||
|
||||
const handle = exports.temporalz_instant_round(
|
||||
this._handle,
|
||||
smallestUnit,
|
||||
roundingMode,
|
||||
roundingIncrement
|
||||
);
|
||||
return Instant._fromHandle(requireHandle(handle));
|
||||
}
|
||||
|
||||
equals(other) {
|
||||
const rhs = Instant.from(other);
|
||||
return exports.temporalz_instant_equals(this._handle, rhs._handle) === 1;
|
||||
}
|
||||
|
||||
toLocaleString() {
|
||||
return this.toString();
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
throw new TypeError("Cannot convert Temporal.Instant to a number");
|
||||
}
|
||||
|
||||
static compare(a, b) {
|
||||
const left = Instant.from(a);
|
||||
const right = Instant.from(b);
|
||||
return Number(exports.temporalz_instant_compare(left._handle, right._handle));
|
||||
}
|
||||
}
|
||||
|
||||
const plainDateHandleToken = Symbol("PlainDateHandle");
|
||||
|
||||
class PlainDate {
|
||||
constructor(year, month, day) {
|
||||
if (year === plainDateHandleToken) {
|
||||
this._handle = month;
|
||||
return;
|
||||
}
|
||||
|
||||
const yearValue = toInteger(year ?? 0, "year");
|
||||
const monthValue = toInteger(month ?? 0, "month");
|
||||
const dayValue = toInteger(day ?? 0, "day");
|
||||
const handle = exports.temporalz_plain_date_init(yearValue, monthValue, dayValue);
|
||||
this._handle = requireHandle(handle);
|
||||
}
|
||||
|
||||
static _fromHandle(handle) {
|
||||
return new PlainDate(plainDateHandleToken, handle);
|
||||
}
|
||||
|
||||
static from(value) {
|
||||
if (value instanceof PlainDate) return value;
|
||||
if (typeof value === "string") {
|
||||
const text = allocString(value);
|
||||
const handle = exports.temporalz_plain_date_from_utf8(text.ptr, text.len);
|
||||
exports.temporalz_free(text.ptr, text.len);
|
||||
return PlainDate._fromHandle(requireHandle(handle));
|
||||
}
|
||||
if (value === null || typeof value !== "object") {
|
||||
throw new TypeError("PlainDate.from expects a string or object");
|
||||
}
|
||||
|
||||
const year = toInteger(value.year, "year");
|
||||
const month = toInteger(value.month, "month");
|
||||
const day = toInteger(value.day, "day");
|
||||
const handle = exports.temporalz_plain_date_init(year, month, day);
|
||||
return PlainDate._fromHandle(requireHandle(handle));
|
||||
}
|
||||
|
||||
toString() {
|
||||
return takeString(exports.temporalz_plain_date_to_string(this._handle));
|
||||
}
|
||||
}
|
||||
|
||||
const durationHandleToken = Symbol("DurationHandle");
|
||||
|
||||
class Duration {
|
||||
constructor(
|
||||
years,
|
||||
months,
|
||||
weeks,
|
||||
days,
|
||||
hours,
|
||||
minutes,
|
||||
seconds,
|
||||
milliseconds,
|
||||
microseconds,
|
||||
nanoseconds
|
||||
) {
|
||||
if (years === durationHandleToken) {
|
||||
this._handle = months;
|
||||
return;
|
||||
}
|
||||
|
||||
const yearsValue = toIntegerBigInt(years ?? 0, "years");
|
||||
const monthsValue = toIntegerBigInt(months ?? 0, "months");
|
||||
const weeksValue = toIntegerBigInt(weeks ?? 0, "weeks");
|
||||
const daysValue = toIntegerBigInt(days ?? 0, "days");
|
||||
const hoursValue = toIntegerBigInt(hours ?? 0, "hours");
|
||||
const minutesValue = toIntegerBigInt(minutes ?? 0, "minutes");
|
||||
const secondsValue = toIntegerBigInt(seconds ?? 0, "seconds");
|
||||
const millisecondsValue = toIntegerBigInt(milliseconds ?? 0, "milliseconds");
|
||||
const microsecondsValue = toNumber(microseconds ?? 0, "microseconds");
|
||||
const nanosecondsValue = toNumber(nanoseconds ?? 0, "nanoseconds");
|
||||
|
||||
const created = exports.temporalz_duration_init(
|
||||
yearsValue,
|
||||
monthsValue,
|
||||
weeksValue,
|
||||
daysValue,
|
||||
hoursValue,
|
||||
minutesValue,
|
||||
secondsValue,
|
||||
millisecondsValue,
|
||||
microsecondsValue,
|
||||
nanosecondsValue
|
||||
);
|
||||
this._handle = requireHandle(created);
|
||||
}
|
||||
|
||||
static _fromHandle(handle) {
|
||||
return new Duration(durationHandleToken, handle);
|
||||
}
|
||||
|
||||
static from(value) {
|
||||
if (value instanceof Duration) return value;
|
||||
if (typeof value === "string") {
|
||||
const text = allocString(value);
|
||||
const handle = exports.temporalz_duration_from_utf8(text.ptr, text.len);
|
||||
exports.temporalz_free(text.ptr, text.len);
|
||||
return Duration._fromHandle(requireHandle(handle));
|
||||
}
|
||||
if (value === null || typeof value !== "object") {
|
||||
throw new TypeError("Duration.from expects a string or object");
|
||||
}
|
||||
|
||||
const fields = [
|
||||
"years",
|
||||
"months",
|
||||
"weeks",
|
||||
"days",
|
||||
"hours",
|
||||
"minutes",
|
||||
"seconds",
|
||||
"milliseconds",
|
||||
"microseconds",
|
||||
"nanoseconds",
|
||||
];
|
||||
|
||||
let mask = 0;
|
||||
const values = [0n, 0n, 0n, 0n, 0n, 0n, 0n, 0n, 0, 0];
|
||||
|
||||
fields.forEach((field, index) => {
|
||||
if (value[field] !== undefined) {
|
||||
mask |= 1 << index;
|
||||
if (field === "microseconds" || field === "nanoseconds") {
|
||||
values[index] = toNumber(value[field], field);
|
||||
} else {
|
||||
values[index] = toIntegerBigInt(value[field], field);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const handle = exports.temporalz_duration_from_parts(
|
||||
mask,
|
||||
values[0],
|
||||
values[1],
|
||||
values[2],
|
||||
values[3],
|
||||
values[4],
|
||||
values[5],
|
||||
values[6],
|
||||
values[7],
|
||||
values[8],
|
||||
values[9]
|
||||
);
|
||||
return Duration._fromHandle(requireHandle(handle));
|
||||
}
|
||||
|
||||
static compare(a, b, options) {
|
||||
const left = Duration.from(a);
|
||||
const right = Duration.from(b);
|
||||
return Duration.compareWithOptions(left, right, options);
|
||||
}
|
||||
|
||||
static compareWithOptions(left, right, options) {
|
||||
if (options !== undefined && (options === null || typeof options !== "object")) {
|
||||
throw new TypeError("options must be an object");
|
||||
}
|
||||
const relativeTo = toRelativeTo(options);
|
||||
if (!relativeTo && (hasYearMonthWeek(left) || hasYearMonthWeek(right))) {
|
||||
throw new RangeError("relativeTo is required for calendar units");
|
||||
}
|
||||
if (relativeTo) {
|
||||
return Number(
|
||||
exports.temporalz_duration_compare_plain_date(
|
||||
left._handle,
|
||||
right._handle,
|
||||
relativeTo._handle
|
||||
)
|
||||
);
|
||||
}
|
||||
return Number(exports.temporalz_duration_compare(left._handle, right._handle));
|
||||
}
|
||||
|
||||
add(other) {
|
||||
const rhs = Duration.from(other);
|
||||
const handle = exports.temporalz_duration_add(this._handle, rhs._handle);
|
||||
return Duration._fromHandle(requireHandle(handle));
|
||||
}
|
||||
|
||||
subtract(other) {
|
||||
const rhs = Duration.from(other);
|
||||
const handle = exports.temporalz_duration_subtract(this._handle, rhs._handle);
|
||||
return Duration._fromHandle(requireHandle(handle));
|
||||
}
|
||||
|
||||
abs() {
|
||||
const handle = exports.temporalz_duration_abs(this._handle);
|
||||
return Duration._fromHandle(requireHandle(handle));
|
||||
}
|
||||
|
||||
negated() {
|
||||
const handle = exports.temporalz_duration_negated(this._handle);
|
||||
return Duration._fromHandle(requireHandle(handle));
|
||||
}
|
||||
|
||||
round(options = {}) {
|
||||
if (options === undefined) options = {};
|
||||
if (options === null || typeof options !== "object") {
|
||||
throw new TypeError("round options must be an object");
|
||||
}
|
||||
const relativeTo = toRelativeTo(options);
|
||||
if (!relativeTo && hasCalendarUnits(this)) {
|
||||
throw new RangeError("relativeTo is required for calendar units");
|
||||
}
|
||||
const smallestUnit = toUnitCode(options.smallestUnit, "smallestUnit");
|
||||
const largestUnit = toUnitCode(options.largestUnit, "largestUnit");
|
||||
const roundingMode = toRoundingModeCode(options.roundingMode);
|
||||
|
||||
let roundingIncrement = 0;
|
||||
if (options.roundingIncrement !== undefined) {
|
||||
const inc = Number(options.roundingIncrement);
|
||||
if (!Number.isFinite(inc) || !Number.isInteger(inc) || inc <= 0) {
|
||||
throw new RangeError("Invalid roundingIncrement");
|
||||
}
|
||||
roundingIncrement = inc;
|
||||
}
|
||||
|
||||
const handle = relativeTo
|
||||
? exports.temporalz_duration_round_plain_date(
|
||||
this._handle,
|
||||
smallestUnit,
|
||||
largestUnit,
|
||||
roundingMode,
|
||||
roundingIncrement,
|
||||
relativeTo._handle
|
||||
)
|
||||
: exports.temporalz_duration_round(
|
||||
this._handle,
|
||||
smallestUnit,
|
||||
largestUnit,
|
||||
roundingMode,
|
||||
roundingIncrement
|
||||
);
|
||||
return Duration._fromHandle(requireHandle(handle));
|
||||
}
|
||||
|
||||
total(options) {
|
||||
if (!options || typeof options !== "object") {
|
||||
throw new TypeError("total options must be an object");
|
||||
}
|
||||
const relativeTo = toRelativeTo(options);
|
||||
if (!relativeTo && hasCalendarUnits(this)) {
|
||||
throw new RangeError("relativeTo is required for calendar units");
|
||||
}
|
||||
const unit = toUnitCode(options.unit, "unit");
|
||||
if (unit === 255) throw new RangeError("Invalid unit");
|
||||
const result = relativeTo
|
||||
? exports.temporalz_duration_total_plain_date(
|
||||
this._handle,
|
||||
unit,
|
||||
relativeTo._handle
|
||||
)
|
||||
: exports.temporalz_duration_total(this._handle, unit);
|
||||
if (!Number.isFinite(result)) throw lastError();
|
||||
return result;
|
||||
}
|
||||
|
||||
get sign() {
|
||||
return Number(exports.temporalz_duration_sign(this._handle));
|
||||
}
|
||||
|
||||
get blank() {
|
||||
return exports.temporalz_duration_blank(this._handle) === 1;
|
||||
}
|
||||
|
||||
toString() {
|
||||
return takeString(exports.temporalz_duration_to_string(this._handle));
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return this.toString();
|
||||
}
|
||||
|
||||
toLocaleString() {
|
||||
return this.toString();
|
||||
}
|
||||
|
||||
valueOf() {
|
||||
throw new TypeError("Cannot convert Temporal.Duration to a number");
|
||||
}
|
||||
|
||||
get years() {
|
||||
return Number(exports.temporalz_duration_years(this._handle));
|
||||
}
|
||||
|
||||
get months() {
|
||||
return Number(exports.temporalz_duration_months(this._handle));
|
||||
}
|
||||
|
||||
get weeks() {
|
||||
return Number(exports.temporalz_duration_weeks(this._handle));
|
||||
}
|
||||
|
||||
get days() {
|
||||
return Number(exports.temporalz_duration_days(this._handle));
|
||||
}
|
||||
|
||||
get hours() {
|
||||
return Number(exports.temporalz_duration_hours(this._handle));
|
||||
}
|
||||
|
||||
get minutes() {
|
||||
return Number(exports.temporalz_duration_minutes(this._handle));
|
||||
}
|
||||
|
||||
get seconds() {
|
||||
return Number(exports.temporalz_duration_seconds(this._handle));
|
||||
}
|
||||
|
||||
get milliseconds() {
|
||||
return Number(exports.temporalz_duration_milliseconds(this._handle));
|
||||
}
|
||||
|
||||
get microseconds() {
|
||||
return Number(exports.temporalz_duration_microseconds(this._handle));
|
||||
}
|
||||
|
||||
get nanoseconds() {
|
||||
return Number(exports.temporalz_duration_nanoseconds(this._handle));
|
||||
}
|
||||
}
|
||||
|
||||
function hasCalendarUnits(duration) {
|
||||
return (
|
||||
duration.years !== 0 ||
|
||||
duration.months !== 0 ||
|
||||
duration.weeks !== 0 ||
|
||||
duration.days !== 0
|
||||
);
|
||||
}
|
||||
|
||||
function hasYearMonthWeek(duration) {
|
||||
return duration.years !== 0 || duration.months !== 0 || duration.weeks !== 0;
|
||||
}
|
||||
|
||||
function toRelativeTo(options) {
|
||||
if (!options || options.relativeTo === undefined) return null;
|
||||
const rel = options.relativeTo;
|
||||
if (rel instanceof PlainDate) return rel;
|
||||
if (typeof rel === "string") return PlainDate.from(rel);
|
||||
if (rel && typeof rel === "object") return PlainDate.from(rel);
|
||||
throw new TypeError("Invalid relativeTo");
|
||||
}
|
||||
|
||||
const Temporal = {
|
||||
Instant,
|
||||
Duration,
|
||||
Now: {
|
||||
instant: unimplemented("Temporal.Now.instant"),
|
||||
plainDateISO: unimplemented("Temporal.Now.plainDateISO"),
|
||||
plainDateTimeISO: unimplemented("Temporal.Now.plainDateTimeISO"),
|
||||
plainTimeISO: unimplemented("Temporal.Now.plainTimeISO"),
|
||||
timeZoneId: unimplemented("Temporal.Now.timeZoneId"),
|
||||
zonedDateTimeISO: unimplemented("Temporal.Now.zonedDateTimeISO"),
|
||||
},
|
||||
PlainDate,
|
||||
PlainTime: unimplemented("Temporal.PlainTime"),
|
||||
PlainDateTime: unimplemented("Temporal.PlainDateTime"),
|
||||
PlainYearMonth: unimplemented("Temporal.PlainYearMonth"),
|
||||
PlainMonthDay: unimplemented("Temporal.PlainMonthDay"),
|
||||
ZonedDateTime: unimplemented("Temporal.ZonedDateTime"),
|
||||
};
|
||||
|
||||
globalThis.Temporal = Temporal;
|
||||
})();
|
||||
35
test/test262/runner.mjs
Normal file
35
test/test262/runner.mjs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import runTest262 from "../temporal-test262-runner/index.mjs";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
const wasmPath =
|
||||
process.env.TEMPORALZ_WASM ||
|
||||
path.resolve(__dirname, "../../zig-out/bin/temporalz.wasm");
|
||||
const wasmBytes = fs.readFileSync(wasmPath);
|
||||
|
||||
const polyfillPath = path.resolve(__dirname, "../test262/polyfill.js");
|
||||
let polyfillCode = fs.readFileSync(polyfillPath, "utf-8");
|
||||
|
||||
const bytesArray = JSON.stringify(Array.from(wasmBytes));
|
||||
// TextEncoder/TextDecoder need to be manually constructed and passed via context
|
||||
// Since we can't serialize them, we inject polyfill-compatible shim versions
|
||||
const injection = `globalThis.__TEMPORALZ_WASM_BYTES__ = new Uint8Array(${bytesArray});
|
||||
`;
|
||||
polyfillCode = injection + polyfillCode;
|
||||
|
||||
const tempPolyfillPath = path.resolve(__dirname, "../test262/polyfill-injected.js");
|
||||
fs.writeFileSync(tempPolyfillPath, polyfillCode);
|
||||
|
||||
const result = runTest262({
|
||||
test262Dir: "test/temporal-test262-runner/test262",
|
||||
polyfillCodeFile: tempPolyfillPath,
|
||||
testGlobs: process.argv.slice(2),
|
||||
});
|
||||
|
||||
fs.unlinkSync(tempPolyfillPath);
|
||||
|
||||
process.exit(result ? 0 : 1);
|
||||
Loading…
Add table
Reference in a new issue