Skip to content

Commit

Permalink
Add: Support wasm32-unknown-emscripten
Browse files Browse the repository at this point in the history
  • Loading branch information
sevenc-nanashi committed Mar 25, 2024
1 parent d91b7d4 commit e4b178c
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 10 deletions.
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ std = ["alloc"]
clock = ["winapi", "iana-time-zone", "android-tzdata", "now"]
now = ["std"]
oldtime = []
wasmbind = ["wasm-bindgen", "js-sys"]
wasmbind = ["wasm-bindgen", "js-sys", "emscripten-functions"]
unstable-locales = ["pure-rust-locales"]
# Note that rkyv-16, rkyv-32, and rkyv-64 are mutually exclusive.
rkyv = ["dep:rkyv", "rkyv/size_32"]
Expand All @@ -49,6 +49,9 @@ arbitrary = { version = "1.0.0", features = ["derive"], optional = true }
wasm-bindgen = { version = "0.2", optional = true }
js-sys = { version = "0.3", optional = true } # contains FFI bindings for the JS Date API

[target.'cfg(all(target_arch = "wasm32", target_os = "emscripten"))'.dependencies]
emscripten-functions = { version = "0.2.1", optional = true }

[target.'cfg(windows)'.dependencies]
windows-targets = { version = "0.52", optional = true }

Expand Down
45 changes: 38 additions & 7 deletions src/offset/local/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::naive::{NaiveDate, NaiveDateTime, NaiveTime};
use crate::Date;
use crate::{DateTime, Utc};

#[cfg(unix)]
#[cfg(all(unix, not(all(target_arch = "wasm32", feature = "wasmbind", target_os = "emscripten"))))]
#[path = "unix.rs"]
mod inner;

Expand All @@ -31,11 +31,7 @@ mod win_bindings;
#[cfg(all(
not(unix),
not(windows),
not(all(
target_arch = "wasm32",
feature = "wasmbind",
not(any(target_os = "emscripten", target_os = "wasi"))
))
not(all(target_arch = "wasm32", feature = "wasmbind", not(target_os = "wasi"),))
))]
mod inner {
use crate::{FixedOffset, MappedLocalTime, NaiveDateTime};
Expand Down Expand Up @@ -92,7 +88,42 @@ mod inner {
}
}

#[cfg(unix)]
#[cfg(all(target_arch = "wasm32", feature = "wasmbind", target_os = "emscripten"))]
mod inner {
use crate::{Datelike, FixedOffset, MappedLocalTime, NaiveDateTime, Timelike};
use emscripten_functions::emscripten::run_script_int;

pub(super) fn offset_from_utc_datetime(utc: &NaiveDateTime) -> MappedLocalTime<FixedOffset> {
let offset = run_script_int(&format!(
"new Date(Date.UTC({}, {}, {}, {}, {}, {}, 0)).getTimezoneOffset()",
utc.year(),
utc.month0() + 1,
utc.day(),
utc.hour(),
utc.minute(),
utc.second()
));
MappedLocalTime::Single(FixedOffset::west_opt((offset as i32) * 60).unwrap())
}

pub(super) fn offset_from_local_datetime(
local: &NaiveDateTime,
) -> MappedLocalTime<FixedOffset> {
let offset = run_script_int(&format!(
"new Date({}, {}, {}, {}, {}, {}, 0).getTimezoneOffset()",
local.year(),
local.month0() + 1,
local.day(),
local.hour(),
local.minute(),
local.second()
));
// We always get a result, even if this time does not exist or is ambiguous.
MappedLocalTime::Single(FixedOffset::west_opt((offset as i32) * 60).unwrap())
}
}

#[cfg(all(unix, not(all(target_arch = "wasm32", feature = "wasmbind", target_os = "emscripten"))))]
mod tz_info;

/// The local timescale.
Expand Down
18 changes: 16 additions & 2 deletions src/offset/utc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use core::fmt;
not(all(
target_arch = "wasm32",
feature = "wasmbind",
not(any(target_os = "emscripten", target_os = "wasi"))
not(target_os = "wasi")
))
))]
use std::time::{SystemTime, UNIX_EPOCH};
Expand Down Expand Up @@ -89,7 +89,7 @@ impl Utc {
#[cfg(not(all(
target_arch = "wasm32",
feature = "wasmbind",
not(any(target_os = "emscripten", target_os = "wasi"))
not(target_os = "wasi")
)))]
#[must_use]
pub fn now() -> DateTime<Utc> {
Expand All @@ -109,6 +109,20 @@ impl Utc {
let now = js_sys::Date::new_0();
DateTime::<Utc>::from(now)
}

/// Returns a `DateTime` which corresponds to the current date and time.
#[cfg(all(
target_arch = "wasm32",
feature = "wasmbind",
target_os = "emscripten"
))]
#[must_use]
pub fn now() -> DateTime<Utc> {
use emscripten_functions::emscripten::run_script_string;
// In order to handle number than i32, string is used to store the number
let now = run_script_string("Date.now().toString()").expect("Date.now() failed").parse::<i64>().unwrap();
Utc.timestamp_millis_opt(now).unwrap()
}
}

impl TimeZone for Utc {
Expand Down

0 comments on commit e4b178c

Please sign in to comment.