Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow optional wasmbindgen #771

Merged
merged 1 commit into from Aug 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/test.yml
Expand Up @@ -173,6 +173,30 @@ jobs:
RUST_VERSION: stable
WASM: wasm_unknown

wasm_unknown_no_wasmbind:
strategy:
matrix:
os: [ubuntu-latest]

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v2

- name: Install rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: wasm32-unknown-unknown
override: true
default: true

- name: Build and Test
run: bash ci/github.sh
env:
RUST_VERSION: stable
WASM: wasm_unknown_no_wasmbind

wasm_wasi:
strategy:
matrix:
Expand Down
8 changes: 4 additions & 4 deletions Cargo.toml
Expand Up @@ -20,13 +20,13 @@ appveyor = { repository = "chronotope/chrono" }
name = "chrono"

[features]
default = ["clock", "std", "oldtime"]
default = ["clock", "std", "oldtime", "wasmbind"]
alloc = []
libc = []
std = []
clock = ["std", "winapi", "iana-time-zone"]
oldtime = ["time"]
wasmbind = [] # TODO: empty feature to avoid breaking change in 0.4.20, can be removed later
wasmbind = ["wasm-bindgen", "js-sys"]
unstable-locales = ["pure-rust-locales", "alloc"]
__internal_bench = ["criterion"]
__doctest = []
Expand All @@ -42,8 +42,8 @@ criterion = { version = "0.3", optional = true }
rkyv = {version = "0.7", optional = true}

[target.'cfg(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi"))))'.dependencies]
wasm-bindgen = { version = "0.2" }
js-sys = { version = "0.3" } # contains FFI bindings for the JS Date API
wasm-bindgen = { version = "0.2", optional = true }
js-sys = { version = "0.3", optional = true } # contains FFI bindings for the JS Date API

[target.'cfg(not(any(target_os = "emscripten", target_os = "wasi", target_os = "solaris")))'.dependencies]
iana-time-zone = { version = "0.1.41", optional = true }
Expand Down
6 changes: 6 additions & 0 deletions ci/github.sh
Expand Up @@ -38,6 +38,8 @@ meaningful in the github actions feature matrix UI.
test_wasm_emscripten
elif [[ ${WASM:-} == wasm_unknown ]]; then
test_wasm_unknown
elif [[ ${WASM:-} == wasm_unknown_no_wasmbind ]]; then
test_wasm_unknown_no_wasmbind
elif [[ ${WASM:-} == wasm_wasi ]]; then
test_wasm_wasi
elif [[ ${CORE:-} == no_std ]]; then
Expand Down Expand Up @@ -126,6 +128,10 @@ test_wasm_unknown() {
runt cargo build --target wasm32-unknown-unknown
}

test_wasm_unknown_no_wasmbind() {
runt cargo build --target wasm32-unknown-unknown --no-default-features --features clock,std
}

test_wasm_wasi() {
runt cargo build --target wasm32-wasi
}
Expand Down
18 changes: 15 additions & 3 deletions src/datetime/mod.rs
Expand Up @@ -994,21 +994,33 @@ impl<Tz: TimeZone> From<DateTime<Tz>> for SystemTime {
}
}

#[cfg(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi"))))]
#[cfg(all(
target_arch = "wasm32",
feature = "wasmbind",
not(any(target_os = "emscripten", target_os = "wasi"))
))]
impl From<js_sys::Date> for DateTime<Utc> {
fn from(date: js_sys::Date) -> DateTime<Utc> {
DateTime::<Utc>::from(&date)
}
}

#[cfg(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi"))))]
#[cfg(all(
target_arch = "wasm32",
feature = "wasmbind",
not(any(target_os = "emscripten", target_os = "wasi"))
))]
impl From<&js_sys::Date> for DateTime<Utc> {
fn from(date: &js_sys::Date) -> DateTime<Utc> {
Utc.timestamp_millis(date.get_time() as i64)
}
}

#[cfg(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi"))))]
#[cfg(all(
target_arch = "wasm32",
feature = "wasmbind",
not(any(target_os = "emscripten", target_os = "wasi"))
))]
impl From<DateTime<Utc>> for js_sys::Date {
/// Converts a `DateTime<Utc>` to a JS `Date`. The resulting value may be lossy,
/// any values that have a millisecond timestamp value greater/less than ±8,640,000,000,000,000
Expand Down
27 changes: 23 additions & 4 deletions src/offset/local/mod.rs
Expand Up @@ -16,7 +16,11 @@ use crate::{Date, DateTime};
#[cfg(all(
not(unix),
not(windows),
not(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi"))))
not(all(
target_arch = "wasm32",
feature = "wasmbind",
not(any(target_os = "emscripten", target_os = "wasi"))
))
))]
#[path = "stub.rs"]
mod inner;
Expand Down Expand Up @@ -59,14 +63,19 @@ impl Local {
/// Returns a `DateTime` which corresponds to the current date and time.
#[cfg(not(all(
target_arch = "wasm32",
feature = "wasmbind",
not(any(target_os = "emscripten", target_os = "wasi"))
)))]
pub fn now() -> DateTime<Local> {
inner::now()
}

/// Returns a `DateTime` which corresponds to the current date and time.
#[cfg(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi"))))]
#[cfg(all(
target_arch = "wasm32",
feature = "wasmbind",
not(any(target_os = "emscripten", target_os = "wasi"))
))]
pub fn now() -> DateTime<Local> {
use super::Utc;
let now: DateTime<Utc> = super::Utc::now();
Expand Down Expand Up @@ -110,7 +119,11 @@ impl TimeZone for Local {
midnight.map(|datetime| Date::from_utc(*local, *datetime.offset()))
}

#[cfg(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi"))))]
#[cfg(all(
target_arch = "wasm32",
feature = "wasmbind",
not(any(target_os = "emscripten", target_os = "wasi"))
))]
fn from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<DateTime<Local>> {
let mut local = local.clone();
// Get the offset from the js runtime
Expand All @@ -121,6 +134,7 @@ impl TimeZone for Local {

#[cfg(not(all(
target_arch = "wasm32",
feature = "wasmbind",
not(any(target_os = "emscripten", target_os = "wasi"))
)))]
fn from_local_datetime(&self, local: &NaiveDateTime) -> LocalResult<DateTime<Local>> {
Expand All @@ -132,7 +146,11 @@ impl TimeZone for Local {
Date::from_utc(*utc, *midnight.offset())
}

#[cfg(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi"))))]
#[cfg(all(
target_arch = "wasm32",
feature = "wasmbind",
not(any(target_os = "emscripten", target_os = "wasi"))
))]
fn from_utc_datetime(&self, utc: &NaiveDateTime) -> DateTime<Local> {
// Get the offset from the js runtime
let offset = FixedOffset::west((js_sys::Date::new_0().get_timezone_offset() as i32) * 60);
Expand All @@ -141,6 +159,7 @@ impl TimeZone for Local {

#[cfg(not(all(
target_arch = "wasm32",
feature = "wasmbind",
not(any(target_os = "emscripten", target_os = "wasi"))
)))]
fn from_utc_datetime(&self, utc: &NaiveDateTime) -> DateTime<Local> {
Expand Down
12 changes: 10 additions & 2 deletions src/offset/local/stub.rs
Expand Up @@ -18,7 +18,11 @@ pub(super) fn now() -> DateTime<Local> {
}

/// Converts a local `NaiveDateTime` to the `time::Timespec`.
#[cfg(not(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi")))))]
#[cfg(not(all(
target_arch = "wasm32",
feature = "wasmbind",
not(any(target_os = "emscripten", target_os = "wasi"))
)))]
pub(super) fn naive_to_local(d: &NaiveDateTime, local: bool) -> LocalResult<DateTime<Local>> {
let tm = Tm {
tm_sec: d.second() as i32,
Expand Down Expand Up @@ -54,7 +58,11 @@ pub(super) fn naive_to_local(d: &NaiveDateTime, local: bool) -> LocalResult<Date

/// Converts a `time::Tm` struct into the timezone-aware `DateTime`.
/// This assumes that `time` is working correctly, i.e. any error is fatal.
#[cfg(not(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi")))))]
#[cfg(not(all(
target_arch = "wasm32",
feature = "wasmbind",
not(any(target_os = "emscripten", target_os = "wasi"))
)))]
fn tm_to_datetime(mut tm: Tm) -> DateTime<Local> {
if tm.tm_sec >= 60 {
tm.tm_nsec += (tm.tm_sec - 59) * 1_000_000_000;
Expand Down
13 changes: 11 additions & 2 deletions src/offset/utc.rs
Expand Up @@ -6,7 +6,11 @@
use core::fmt;
#[cfg(all(
feature = "clock",
not(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi"))))
not(all(
target_arch = "wasm32",
feature = "wasmbind",
not(any(target_os = "emscripten", target_os = "wasi"))
))
))]
use std::time::{SystemTime, UNIX_EPOCH};

Expand Down Expand Up @@ -49,6 +53,7 @@ impl Utc {
/// Returns a `DateTime` which corresponds to the current date and time.
#[cfg(not(all(
target_arch = "wasm32",
feature = "wasmbind",
not(any(target_os = "emscripten", target_os = "wasi"))
)))]
pub fn now() -> DateTime<Utc> {
Expand All @@ -59,7 +64,11 @@ impl Utc {
}

/// Returns a `DateTime` which corresponds to the current date and time.
#[cfg(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi"))))]
#[cfg(all(
target_arch = "wasm32",
feature = "wasmbind",
not(any(target_os = "emscripten", target_os = "wasi"))
))]
pub fn now() -> DateTime<Utc> {
let now = js_sys::Date::new_0();
DateTime::<Utc>::from(now)
Expand Down
6 changes: 5 additions & 1 deletion tests/wasm.rs
@@ -1,4 +1,8 @@
#![cfg(all(target_arch = "wasm32", not(any(target_os = "emscripten", target_os = "wasi"))))]
#![cfg(all(
target_arch = "wasm32",
feature = "wasmbind",
not(any(target_os = "emscripten", target_os = "wasi"))
))]

use self::chrono::prelude::*;
use self::wasm_bindgen_test::*;
Expand Down