diff options
author | David LeGare <legare@google.com> | 2022-03-08 00:16:09 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2022-03-08 00:16:09 +0000 |
commit | acf6b4e663cdd33562797ddc67ae0c2f9137e387 (patch) | |
tree | 4a79f8bd26d95e83102eaa2bd02e03a49b61a4cb | |
parent | f18fa1fa75f47e4b23b11222e390b42aabf9c88b (diff) | |
parent | b753132403ede7933e83400971c712807b75068b (diff) | |
download | instant-acf6b4e663cdd33562797ddc67ae0c2f9137e387.tar.gz |
Update instant to 0.1.12 am: 5c021f60af am: ca9a1ef140 am: b753132403
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/instant/+/2004852
Change-Id: Ia364025f898beac9c29af909e696bb95d60909e9
-rw-r--r-- | .cargo_vcs_info.json | 2 | ||||
-rw-r--r-- | .circleci/config.yml | 64 | ||||
-rw-r--r-- | .gitignore | 24 | ||||
-rw-r--r-- | AUTHORS | 2 | ||||
-rw-r--r-- | Android.bp | 2 | ||||
-rw-r--r-- | CHANGELOGS.md | 7 | ||||
-rw-r--r-- | Cargo.toml | 16 | ||||
-rw-r--r-- | Cargo.toml.orig | 81 | ||||
-rw-r--r-- | LICENSE | 54 | ||||
-rw-r--r-- | METADATA | 10 | ||||
-rw-r--r-- | README.md | 287 | ||||
-rw-r--r-- | src/lib.rs | 44 | ||||
-rw-r--r-- | src/native.rs | 16 | ||||
-rw-r--r-- | src/wasm.rs | 384 | ||||
-rw-r--r-- | tests/wasm.rs | 106 |
15 files changed, 602 insertions, 497 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 56bc629..75ac2a1 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,5 @@ { "git": { - "sha1": "1f72ffddf0dbc4e6905d8543d113324d6967e038" + "sha1": "9a486adeee119bdf7ecb85ba627b8112fb7eff86" } } diff --git a/.circleci/config.yml b/.circleci/config.yml index 878e288..d5c0159 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,33 +1,33 @@ -version: 2.1 - -executors: - rust-executor: - docker: - - image: rust:latest - -jobs: - build: - executor: rust-executor - steps: - - checkout - - run: - name: install cargo-web - command: cargo install -f cargo-web; - - run: - name: build - command: cargo build --verbose; - - run: - name: build --features stdweb - command: cargo web build --verbose --target wasm32-unknown-unknown --features "stdweb"; - - run: - name: build --features wasm-bindgen - command: cargo build --verbose --target wasm32-unknown-unknown --features "wasm-bindgen"; - - run: - name: build --features now - command: cargo build --verbose --features now; - - run: - name: build --features now stdweb - command: cargo web build --verbose --target wasm32-unknown-unknown --features "now stdweb"; - - run: - name: build --features now wasm-bindgen +version: 2.1
+
+executors:
+ rust-executor:
+ docker:
+ - image: rust:latest
+
+jobs:
+ build:
+ executor: rust-executor
+ steps:
+ - checkout
+ - run:
+ name: install cargo-web
+ command: cargo install -f cargo-web;
+ - run:
+ name: build
+ command: cargo build --verbose;
+ - run:
+ name: build --features stdweb
+ command: cargo web build --verbose --target wasm32-unknown-unknown --features "stdweb";
+ - run:
+ name: build --features wasm-bindgen
+ command: cargo build --verbose --target wasm32-unknown-unknown --features "wasm-bindgen";
+ - run:
+ name: build --features now
+ command: cargo build --verbose --features now;
+ - run:
+ name: build --features now stdweb
+ command: cargo web build --verbose --target wasm32-unknown-unknown --features "now stdweb";
+ - run:
+ name: build --features now wasm-bindgen
command: cargo build --verbose --target wasm32-unknown-unknown --features "now wasm-bindgen";
\ No newline at end of file @@ -1,12 +1,12 @@ -*.swp -*.swo -*.so -*.rlib -*.dSYM -*.dylib -cargo.lock -Cargo.lock -target -.idea -wasm-pack.log -bin +*.swp
+*.swo
+*.so
+*.rlib
+*.dSYM
+*.dylib
+cargo.lock
+Cargo.lock
+target
+.idea
+wasm-pack.log
+bin
@@ -1,2 +1,2 @@ -Main developer: +Main developer:
* Sébastien Crozet <developer@crozet.re>
\ No newline at end of file @@ -23,7 +23,7 @@ rust_library { host_supported: true, crate_name: "instant", cargo_env_compat: true, - cargo_pkg_version: "0.1.10", + cargo_pkg_version: "0.1.12", srcs: ["src/lib.rs"], edition: "2018", rustlibs: [ diff --git a/CHANGELOGS.md b/CHANGELOGS.md new file mode 100644 index 0000000..092d8ae --- /dev/null +++ b/CHANGELOGS.md @@ -0,0 +1,7 @@ +# v0.1.12
+## Added
+- Add `SystemTime` which works in both native and WASM environments.
+
+## Modified
+- The `now` function is always available now: there is no need to enable the `now` feature any more. The `now` feature
+ still exists (but doesn’t do anything) for backwards compatibility.
\ No newline at end of file @@ -3,17 +3,16 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies +# to registry (e.g., crates.io) dependencies. # -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. [package] edition = "2018" name = "instant" -version = "0.1.10" +version = "0.1.12" authors = ["sebcrozet <developer@crozet.re>"] description = "A partial replacement for std::time::Instant that works on WASM too." readme = "README.md" @@ -27,7 +26,7 @@ version = "0.3" [features] inaccurate = [] -now = ["time"] +now = [] wasm-bindgen = ["js-sys", "wasm-bindgen_rs", "web-sys"] [target.asmjs-unknown-emscripten.dependencies.js-sys] version = "0.3" @@ -46,9 +45,6 @@ package = "wasm-bindgen" version = "0.3" features = ["Window", "Performance", "PerformanceTiming"] optional = true -[target."cfg(not(any(feature = \"stdweb\", feature = \"wasm-bindgen\")))".dependencies.time] -version = "0.2" -optional = true [target.wasm32-unknown-emscripten.dependencies.js-sys] version = "0.3" optional = true diff --git a/Cargo.toml.orig b/Cargo.toml.orig index 7cd1dc4..8d55bd8 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -1,42 +1,39 @@ -[package] -name = "instant" -version = "0.1.10" -authors = ["sebcrozet <developer@crozet.re>"] -description = "A partial replacement for std::time::Instant that works on WASM too." -repository = "https://github.com/sebcrozet/instant" -readme = "README.md" -license = "BSD-3-Clause" -keywords = [ "time", "wasm" ] -edition = "2018" - -[features] -now = [ "time" ] -wasm-bindgen = ["js-sys", "wasm-bindgen_rs", "web-sys"] -inaccurate = [] - -[dependencies] -cfg-if = "1.0" - -[target.'cfg(not(any(feature = "stdweb", feature = "wasm-bindgen")))'.dependencies] -time = { version = "0.2", optional = true } - -[target.wasm32-unknown-unknown.dependencies] -js-sys = { version = "0.3", optional = true } -stdweb = { version = "0.4", optional = true } -wasm-bindgen_rs = { package = "wasm-bindgen", version = "0.2", optional = true } -web-sys = { version = "0.3", optional = true, features = ['Window', 'Performance', 'PerformanceTiming'] } - -[target.wasm32-unknown-emscripten.dependencies] -js-sys = { version = "0.3", optional = true } -stdweb = { version = "0.4", optional = true } -wasm-bindgen_rs = { package = "wasm-bindgen", version = "0.2", optional = true } -web-sys = { version = "0.3", optional = true, features = ['Window', 'Performance', 'PerformanceTiming'] } - -[target.asmjs-unknown-emscripten.dependencies] -js-sys = { version = "0.3", optional = true } -stdweb = { version = "0.4", optional = true } -wasm-bindgen_rs = { package = "wasm-bindgen", version = "0.2", optional = true } -web-sys = { version = "0.3", optional = true, features = ['Window', 'Performance', 'PerformanceTiming'] } - -[dev-dependencies] -wasm-bindgen-test = "0.3" +[package]
+name = "instant"
+version = "0.1.12"
+authors = ["sebcrozet <developer@crozet.re>"]
+description = "A partial replacement for std::time::Instant that works on WASM too."
+repository = "https://github.com/sebcrozet/instant"
+readme = "README.md"
+license = "BSD-3-Clause"
+keywords = [ "time", "wasm" ]
+edition = "2018"
+
+[features]
+wasm-bindgen = ["js-sys", "wasm-bindgen_rs", "web-sys"]
+inaccurate = []
+now = []
+
+[dependencies]
+cfg-if = "1.0"
+
+[target.wasm32-unknown-unknown.dependencies]
+js-sys = { version = "0.3", optional = true }
+stdweb = { version = "0.4", optional = true }
+wasm-bindgen_rs = { package = "wasm-bindgen", version = "0.2", optional = true }
+web-sys = { version = "0.3", optional = true, features = ['Window', 'Performance', 'PerformanceTiming'] }
+
+[target.wasm32-unknown-emscripten.dependencies]
+js-sys = { version = "0.3", optional = true }
+stdweb = { version = "0.4", optional = true }
+wasm-bindgen_rs = { package = "wasm-bindgen", version = "0.2", optional = true }
+web-sys = { version = "0.3", optional = true, features = ['Window', 'Performance', 'PerformanceTiming'] }
+
+[target.asmjs-unknown-emscripten.dependencies]
+js-sys = { version = "0.3", optional = true }
+stdweb = { version = "0.4", optional = true }
+wasm-bindgen_rs = { package = "wasm-bindgen", version = "0.2", optional = true }
+web-sys = { version = "0.3", optional = true, features = ['Window', 'Performance', 'PerformanceTiming'] }
+
+[dev-dependencies]
+wasm-bindgen-test = "0.3"
@@ -1,27 +1,27 @@ -Copyright (c) 2019, Sébastien Crozet -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the author nor the names of its contributors may be used - to endorse or promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +Copyright (c) 2019, Sébastien Crozet
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+3. Neither the name of the author nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/instant/instant-0.1.10.crate" + value: "https://static.crates.io/crates/instant/instant-0.1.12.crate" } - version: "0.1.10" + version: "0.1.12" license_type: NOTICE last_upgrade_date { - year: 2021 - month: 8 - day: 9 + year: 2022 + month: 3 + day: 1 } } @@ -1,144 +1,143 @@ -# Instant - -If you call `std::time::Instant::now()` on a WASM platform, it will panic. This crate provides a partial -replacement for `std::time::Instant` that works on WASM too. This defines the type `instant::Instant` which is: - -* A struct emulating the behavior of **std::time::Instant** if you are targeting `wasm32-unknown-unknown` or `wasm32-unknown-asmjs` -**and** you enabled either the `stdweb` or the `wasm-bindgen` feature. This emulation is based on the javascript `performance.now()` function. -* A type alias for `std::time::Instant` otherwise. - - - -Note that even if the **stdweb** or **wasm-bindgen** feature is enabled, this crate will continue to rely on `std::time::Instant` -as long as you are not targeting wasm32. This allows for portable code that will work on both native and WASM platforms. - -### The feature `now`. -By enabling the feature `now` the function `instant::now()` will be exported and will either: - -* Call `performance.now()` when compiling for a WASM platform with the features **stdweb** or **wasm-bindgen** enabled, or using a custom javascript function. -* Call `time::precise_time_s() * 1000.0` otherwise. - -The result is expressed in milliseconds. - -## Examples -### Using `instant` for a native platform. -_Cargo.toml_: -```toml -[dependencies] -instant = "0.1" -``` - -_main.rs_: -```rust -fn main() { - // Will be the same as `std::time::Instant`. - let now = instant::Instant::new(); -} -``` - ------ - -### Using `instant` for a WASM platform. -This example shows the use of the `stdweb` feature. It would be similar with `wasm-bindgen`. - -_Cargo.toml_: -```toml -[dependencies] -instant = { version = "0.1", features = [ "stdweb" ] } -``` - -_main.rs_: -```rust -fn main() { - // Will emulate `std::time::Instant` based on `performance.now()`. - let now = instant::Instant::new(); -} -``` - ------ - -### Using `instant` for a WASM platform where `performance.now()` is not available. -This example shows the use of the `inaccurate` feature. - -_Cargo.toml_: -```toml -[dependencies] -instant = { version = "0.1", features = [ "wasm-bindgen", "inaccurate" ] } -``` - -_main.rs_: -```rust -fn main() { - // Will emulate `std::time::Instant` based on `Date.now()`. - let now = instant::Instant::new(); -} -``` - - ------ - -### Using `instant` for any platform enabling a feature transitively. -_Cargo.toml_: -```toml -[features] -stdweb = [ "instant/stdweb" ] -wasm-bindgen = [ "instant/wasm-bindgen" ] - -[dependencies] -instant = "0.1" -``` - -_lib.rs_: -```rust -fn my_function() { - // Will select the proper implementation depending on the - // feature selected by the user. - let now = instant::Instant::new(); -} -``` - ------ - -### Using the feature `now`. -_Cargo.toml_: -```toml -[features] -stdweb = [ "instant/stdweb" ] -wasm-bindgen = [ "instant/wasm-bindgen" ] - -[dependencies] -instant = { version = "0.1", features = [ "now" ] } -``` - -_lib.rs_: -```rust -fn my_function() { - // Will select the proper implementation depending on the - // feature selected by the user. - let now_instant = instant::Instant::new(); - let now_milliseconds = instant::now(); // In milliseconds. -} -``` - -### Using the feature `now` without `stdweb` or `wasm-bindgen`. -_Cargo.toml_: -```toml -[dependencies] -instant = { version = "0.", features = [ "now" ] } -``` - -_lib.rs_: -```rust -fn my_function() { - // Will use the 'now' javascript implementation. - let now_instant = instant::Instant::new(); - let now_milliseconds = instant::now(); // In milliseconds. -} -``` - -_javascript WASM bindings file_: -```js -function now() { - return Date.now() / 1000.0; -} -``` +# Instant
+
+If you call `std::time::Instant::now()` on a WASM platform, it will panic. This crate provides a partial
+replacement for `std::time::Instant` that works on WASM too. This defines the type `instant::Instant` which is:
+
+* A struct emulating the behavior of **std::time::Instant** if you are targeting `wasm32-unknown-unknown` or `wasm32-unknown-asmjs`
+**and** you enabled either the `stdweb` or the `wasm-bindgen` feature. This emulation is based on the javascript `performance.now()` function.
+* A type alias for `std::time::Instant` otherwise.
+
+
+
+Note that even if the **stdweb** or **wasm-bindgen** feature is enabled, this crate will continue to rely on `std::time::Instant`
+as long as you are not targeting wasm32. This allows for portable code that will work on both native and WASM platforms.
+
+This crate also exports the function `instant::now()` which returns a representation of the current time as an `f64`, expressed in milliseconds, in a platform-agnostic way. `instant::now()` will either:
+
+* Call `performance.now()` when compiling for a WASM platform with the features **stdweb** or **wasm-bindgen** enabled, or using a custom javascript function.
+* Return the time elapsed since the *Unix Epoch* on *native*, *non-WASM* platforms.
+
+*Note*: The old feature, `now`, has been deprecated. `instant::now()` is always exported and the `now` feature flag no longer has any effect. It remains listed in `Cargo.toml` to avoid introducing breaking changes and may be removed in future versions.
+
+## Examples
+### Using `instant` for a native platform.
+_Cargo.toml_:
+```toml
+[dependencies]
+instant = "0.1"
+```
+
+_main.rs_:
+```rust
+fn main() {
+ // Will be the same as `std::time::Instant`.
+ let now = instant::Instant::now();
+}
+```
+
+-----
+
+### Using `instant` for a WASM platform.
+This example shows the use of the `stdweb` feature. It would be similar with `wasm-bindgen`.
+
+_Cargo.toml_:
+```toml
+[dependencies]
+instant = { version = "0.1", features = [ "stdweb" ] }
+```
+
+_main.rs_:
+```rust
+fn main() {
+ // Will emulate `std::time::Instant` based on `performance.now()`.
+ let now = instant::Instant::now();
+}
+```
+
+-----
+
+### Using `instant` for a WASM platform where `performance.now()` is not available.
+This example shows the use of the `inaccurate` feature.
+
+_Cargo.toml_:
+```toml
+[dependencies]
+instant = { version = "0.1", features = [ "wasm-bindgen", "inaccurate" ] }
+```
+
+_main.rs_:
+```rust
+fn main() {
+ // Will emulate `std::time::Instant` based on `Date.now()`.
+ let now = instant::Instant::now();
+}
+```
+
+
+-----
+
+### Using `instant` for any platform enabling a feature transitively.
+_Cargo.toml_:
+```toml
+[features]
+stdweb = [ "instant/stdweb" ]
+wasm-bindgen = [ "instant/wasm-bindgen" ]
+
+[dependencies]
+instant = "0.1"
+```
+
+_lib.rs_:
+```rust
+fn my_function() {
+ // Will select the proper implementation depending on the
+ // feature selected by the user.
+ let now = instant::Instant::now();
+}
+```
+
+-----
+
+### Using `instant::now()`
+_Cargo.toml_:
+```toml
+[features]
+stdweb = [ "instant/stdweb" ]
+wasm-bindgen = [ "instant/wasm-bindgen" ]
+
+[dependencies]
+instant = "0.1"
+```
+
+_lib.rs_:
+```rust
+fn my_function() {
+ // Will select the proper implementation depending on the
+ // feature selected by the user.
+ let now_instant = instant::Instant::now();
+ let now_milliseconds = instant::now(); // In milliseconds.
+}
+```
+
+### Using the feature `now` without `stdweb` or `wasm-bindgen`.
+_Cargo.toml_:
+```toml
+[dependencies]
+instant = "0.1"
+```
+
+_lib.rs_:
+```rust
+fn my_function() {
+ // Will use the 'now' javascript implementation.
+ let now_instant = instant::Instant::now();
+ let now_milliseconds = instant::now(); // In milliseconds.
+}
+```
+
+_javascript WASM bindings file_:
+```js
+function now() {
+ return Date.now() / 1000.0;
+}
+```
@@ -1,22 +1,22 @@ -cfg_if::cfg_if! { - if #[cfg(any( - all(target_arch = "wasm32", not(target_os = "wasi")), - target_arch = "asmjs" - ))] { - #[cfg(all(feature = "stdweb", not(feature = "wasm-bindgen")))] - #[macro_use] - extern crate stdweb; - - mod wasm; - pub use wasm::Instant; - #[cfg(feature = "now")] - pub use crate::wasm::now; - } else { - mod native; - pub use native::Instant; - #[cfg(feature = "now")] - pub use native::now; - } -} - -pub use std::time::Duration; +cfg_if::cfg_if! {
+ if #[cfg(any(
+ all(target_arch = "wasm32", not(target_os = "wasi")),
+ target_arch = "asmjs"
+ ))] {
+ #[cfg(all(feature = "stdweb", not(feature = "wasm-bindgen")))]
+ #[macro_use]
+ extern crate stdweb;
+
+ mod wasm;
+ pub use wasm::Instant;
+ pub use crate::wasm::now;
+ pub use wasm::SystemTime;
+ } else {
+ mod native;
+ pub use native::Instant;
+ pub use native::now;
+ pub use native::SystemTime;
+ }
+}
+
+pub use std::time::Duration;
diff --git a/src/native.rs b/src/native.rs index 37d5da4..37b34f3 100644 --- a/src/native.rs +++ b/src/native.rs @@ -1,7 +1,9 @@ -pub type Instant = std::time::Instant; - -/// The current time, in milliseconds. -#[cfg(feature = "now")] -pub fn now() -> f64 { - time::precise_time_s() * 1000.0 -} +pub type Instant = std::time::Instant;
+pub type SystemTime = std::time::SystemTime;
+
+/// The current time, expressed in milliseconds since the Unix Epoch.
+pub fn now() -> f64 {
+ std::time::SystemTime::now().duration_since(std::time::SystemTime::UNIX_EPOCH)
+ .expect("System clock was before 1970.")
+ .as_secs_f64() * 1000.0
+}
diff --git a/src/wasm.rs b/src/wasm.rs index 57ea39c..f11b82a 100644 --- a/src/wasm.rs +++ b/src/wasm.rs @@ -1,144 +1,240 @@ -use std::ops::{Add, AddAssign, Sub, SubAssign}; -use std::time::Duration; - -#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Hash)] -pub struct Instant(Duration); - -impl Ord for Instant { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { - self.partial_cmp(other) - .expect("an instant should never be NaN or Inf.") - } -} -impl Eq for Instant {} - -impl Instant { - #[inline] - pub fn now() -> Self { - Instant(duration_from_f64(now())) - } - - #[inline] - pub fn duration_since(&self, earlier: Instant) -> Duration { - assert!( - earlier.0 <= self.0, - "`earlier` cannot be later than `self`." - ); - self.0 - earlier.0 - } - - #[inline] - pub fn elapsed(&self) -> Duration { - Self::now().duration_since(*self) - } - - /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be represented as - /// `Instant` (which means it's inside the bounds of the underlying data structure), `None` - /// otherwise. - #[inline] - pub fn checked_add(&self, duration: Duration) -> Option<Instant> { - self.0.checked_add(duration).map(Instant) - } - - /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as - /// `Instant` (which means it's inside the bounds of the underlying data structure), `None` - /// otherwise. - #[inline] - pub fn checked_sub(&self, duration: Duration) -> Option<Instant> { - self.0.checked_sub(duration).map(Instant) - } -} - -impl Add<Duration> for Instant { - type Output = Self; - - #[inline] - fn add(self, rhs: Duration) -> Self { - Instant(self.0 + rhs) - } -} - -impl AddAssign<Duration> for Instant { - #[inline] - fn add_assign(&mut self, rhs: Duration) { - self.0 += rhs - } -} - -impl Sub<Duration> for Instant { - type Output = Self; - - #[inline] - fn sub(self, rhs: Duration) -> Self { - Instant(self.0 - rhs) - } -} - -impl Sub<Instant> for Instant { - type Output = Duration; - - #[inline] - fn sub(self, rhs: Instant) -> Duration { - self.duration_since(rhs) - } -} - -impl SubAssign<Duration> for Instant { - #[inline] - fn sub_assign(&mut self, rhs: Duration) { - self.0 -= rhs - } -} - -fn duration_from_f64(millis: f64) -> Duration { - Duration::from_millis(millis.trunc() as u64) - + Duration::from_nanos((millis.fract() * 1.0e6) as u64) -} - -#[cfg(all(feature = "stdweb", not(feature = "wasm-bindgen")))] -#[allow(unused_results)] // Needed because the js macro triggers it. -pub fn now() -> f64 { - use stdweb::unstable::TryInto; - - // https://developer.mozilla.org/en-US/docs/Web/API/Performance/now - #[cfg(not(feature = "inaccurate"))] - let v = js! { return performance.now(); }; - #[cfg(feature = "inaccurate")] - let v = js! { return Date.now(); }; - v.try_into().unwrap() -} - -#[cfg(feature = "wasm-bindgen")] -pub fn now() -> f64 { - #[cfg(not(feature = "inaccurate"))] - let now = { - use wasm_bindgen_rs::prelude::*; - use wasm_bindgen_rs::JsCast; - js_sys::Reflect::get(&js_sys::global(), &JsValue::from_str("performance")) - .expect("failed to get performance from global object") - .unchecked_into::<web_sys::Performance>() - .now() - }; - #[cfg(feature = "inaccurate")] - let now = js_sys::Date::now(); - now -} - -// The JS now function is in a module so it won't have to be renamed -#[cfg(not(any(feature = "wasm-bindgen", feature = "stdweb")))] -mod js { - extern "C" { - #[cfg(not(target_os = "emscripten"))] - pub fn now() -> f64; - #[cfg(target_os = "emscripten")] - pub fn _emscripten_get_now() -> f64; - } -} -// Make the unsafe extern function "safe" so it can be called like the other 'now' functions -#[cfg(not(any(feature = "wasm-bindgen", feature = "stdweb")))] -pub fn now() -> f64 { - #[cfg(not(target_os = "emscripten"))] - return unsafe { js::now() }; - #[cfg(target_os = "emscripten")] - return unsafe { js::_emscripten_get_now() }; -} +use std::cmp::Ordering;
+use std::ops::{Add, AddAssign, Sub, SubAssign};
+use std::time::Duration;
+
+#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Hash)]
+pub struct Instant(Duration);
+
+impl Ord for Instant {
+ fn cmp(&self, other: &Self) -> std::cmp::Ordering {
+ self.partial_cmp(other)
+ .expect("an instant should never be NaN or Inf.")
+ }
+}
+impl Eq for Instant {}
+
+impl Instant {
+ #[inline]
+ pub fn now() -> Self {
+ Instant(duration_from_f64(now()))
+ }
+
+ #[inline]
+ pub fn duration_since(&self, earlier: Instant) -> Duration {
+ assert!(
+ earlier.0 <= self.0,
+ "`earlier` cannot be later than `self`."
+ );
+ self.0 - earlier.0
+ }
+
+ #[inline]
+ pub fn elapsed(&self) -> Duration {
+ Self::now().duration_since(*self)
+ }
+
+ /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be represented as
+ /// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
+ /// otherwise.
+ #[inline]
+ pub fn checked_add(&self, duration: Duration) -> Option<Instant> {
+ self.0.checked_add(duration).map(Instant)
+ }
+
+ /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be represented as
+ /// `Instant` (which means it's inside the bounds of the underlying data structure), `None`
+ /// otherwise.
+ #[inline]
+ pub fn checked_sub(&self, duration: Duration) -> Option<Instant> {
+ self.0.checked_sub(duration).map(Instant)
+ }
+
+ /// Returns the amount of time elapsed from another instant to this one, or None if that
+ /// instant is later than this one.
+ #[inline]
+ pub fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> {
+ if earlier.0 > self.0 {
+ None
+ } else {
+ Some(self.0 - earlier.0)
+ }
+ }
+
+ /// Returns the amount of time elapsed from another instant to this one, or zero duration if
+ /// that instant is later than this one.
+ #[inline]
+ pub fn saturating_duration_since(&self, earlier: Instant) -> Duration {
+ self.checked_duration_since(earlier).unwrap_or_default()
+ }
+}
+
+impl Add<Duration> for Instant {
+ type Output = Self;
+
+ #[inline]
+ fn add(self, rhs: Duration) -> Self {
+ Instant(self.0 + rhs)
+ }
+}
+
+impl AddAssign<Duration> for Instant {
+ #[inline]
+ fn add_assign(&mut self, rhs: Duration) {
+ self.0 += rhs
+ }
+}
+
+impl Sub<Duration> for Instant {
+ type Output = Self;
+
+ #[inline]
+ fn sub(self, rhs: Duration) -> Self {
+ Instant(self.0 - rhs)
+ }
+}
+
+impl Sub<Instant> for Instant {
+ type Output = Duration;
+
+ #[inline]
+ fn sub(self, rhs: Instant) -> Duration {
+ self.duration_since(rhs)
+ }
+}
+
+impl SubAssign<Duration> for Instant {
+ #[inline]
+ fn sub_assign(&mut self, rhs: Duration) {
+ self.0 -= rhs
+ }
+}
+
+fn duration_from_f64(millis: f64) -> Duration {
+ Duration::from_millis(millis.trunc() as u64)
+ + Duration::from_nanos((millis.fract() * 1.0e6) as u64)
+}
+
+#[cfg(all(feature = "stdweb", not(feature = "wasm-bindgen")))]
+#[allow(unused_results)] // Needed because the js macro triggers it.
+pub fn now() -> f64 {
+ use stdweb::unstable::TryInto;
+
+ // https://developer.mozilla.org/en-US/docs/Web/API/Performance/now
+ #[cfg(not(feature = "inaccurate"))]
+ let v = js! { return performance.now(); };
+ #[cfg(feature = "inaccurate")]
+ let v = js! { return Date.now(); };
+ v.try_into().unwrap()
+}
+
+#[cfg(feature = "wasm-bindgen")]
+pub fn now() -> f64 {
+ #[cfg(not(feature = "inaccurate"))]
+ let now = {
+ use wasm_bindgen_rs::prelude::*;
+ use wasm_bindgen_rs::JsCast;
+ js_sys::Reflect::get(&js_sys::global(), &JsValue::from_str("performance"))
+ .expect("failed to get performance from global object")
+ .unchecked_into::<web_sys::Performance>()
+ .now()
+ };
+ #[cfg(feature = "inaccurate")]
+ let now = js_sys::Date::now();
+ now
+}
+
+// The JS now function is in a module so it won't have to be renamed
+#[cfg(not(any(feature = "wasm-bindgen", feature = "stdweb")))]
+mod js {
+ extern "C" {
+ #[cfg(not(target_os = "emscripten"))]
+ pub fn now() -> f64;
+ #[cfg(target_os = "emscripten")]
+ pub fn _emscripten_get_now() -> f64;
+ }
+}
+// Make the unsafe extern function "safe" so it can be called like the other 'now' functions
+#[cfg(not(any(feature = "wasm-bindgen", feature = "stdweb")))]
+pub fn now() -> f64 {
+ #[cfg(not(target_os = "emscripten"))]
+ return unsafe { js::now() };
+ #[cfg(target_os = "emscripten")]
+ return unsafe { js::_emscripten_get_now() };
+}
+
+/// Returns the number of millisecods elapsed since January 1, 1970 00:00:00 UTC.
+#[cfg(any(feature = "wasm-bindgen", feature = "stdweb"))]
+fn get_time() -> f64 {
+ #[cfg(feature = "wasm-bindgen")]
+ return js_sys::Date::now();
+ #[cfg(all(feature = "stdweb", not(feature = "wasm-bindgen")))]
+ {
+ let v = js! { return Date.now(); };
+ return v.try_into().unwrap();
+ }
+}
+
+#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
+pub struct SystemTime(f64);
+
+impl SystemTime {
+ pub const UNIX_EPOCH: SystemTime = SystemTime(0.0);
+
+ pub fn now() -> SystemTime {
+ cfg_if::cfg_if! {
+ if #[cfg(any(feature = "wasm-bindgen", feature = "stdweb"))] {
+ SystemTime(get_time())
+ } else {
+ SystemTime(now())
+ }
+ }
+ }
+
+ pub fn duration_since(&self, earlier: SystemTime) -> Result<Duration, ()> {
+ let dur_ms = self.0 - earlier.0;
+ if dur_ms < 0.0 {
+ return Err(());
+ }
+ Ok(Duration::from_millis(dur_ms as u64))
+ }
+
+ pub fn elapsed(&self) -> Result<Duration, ()> {
+ self.duration_since(SystemTime::now())
+ }
+
+ pub fn checked_add(&self, duration: Duration) -> Option<SystemTime> {
+ Some(*self + duration)
+ }
+
+ pub fn checked_sub(&self, duration: Duration) -> Option<SystemTime> {
+ Some(*self - duration)
+ }
+}
+
+impl Add<Duration> for SystemTime {
+ type Output = SystemTime;
+
+ fn add(self, other: Duration) -> SystemTime {
+ SystemTime(self.0 + other.as_millis() as f64)
+ }
+}
+
+impl Sub<Duration> for SystemTime {
+ type Output = SystemTime;
+
+ fn sub(self, other: Duration) -> SystemTime {
+ SystemTime(self.0 - other.as_millis() as f64)
+ }
+}
+
+impl AddAssign<Duration> for SystemTime {
+ fn add_assign(&mut self, rhs: Duration) {
+ *self = *self + rhs;
+ }
+}
+
+impl SubAssign<Duration> for SystemTime {
+ fn sub_assign(&mut self, rhs: Duration) {
+ *self = *self - rhs;
+ }
+}
diff --git a/tests/wasm.rs b/tests/wasm.rs index 863eefd..7dacdc4 100644 --- a/tests/wasm.rs +++ b/tests/wasm.rs @@ -1,49 +1,57 @@ -extern crate wasm_bindgen_test; - -use instant::Instant; -use std::time::Duration; -use wasm_bindgen_test::*; - -wasm_bindgen_test_configure!(run_in_browser); -// run these tests using: wasm-pack test --chrome --headless -- --features wasm-bindgen - -#[wasm_bindgen_test] -fn test_instant_now() { - let now = Instant::now(); - #[cfg(feature = "inaccurate")] - while now.elapsed().as_millis() == 0 {} - #[cfg(not(feature = "inaccurate"))] - assert!(now.elapsed().as_nanos() > 0); -} - -#[wasm_bindgen_test] -fn test_duration() { - let now = Instant::now(); - let one_sec = Duration::from_secs(1); - assert!(now.elapsed() < one_sec); -} - -// Duration::new will overflow when you have u64::MAX seconds and one billion nanoseconds. -// <https://doc.rust-lang.org/std/time/struct.Duration.html#method.new> -const ONE_BILLION: u32 = 1_000_000_000; - -#[wasm_bindgen_test] -fn test_checked_add() { - let now = Instant::now(); - - assert!(now.checked_add(Duration::from_millis(1)).is_some()); - assert_eq!( - None, - now.checked_add(Duration::new(u64::MAX, ONE_BILLION - 1)) - ); -} - -#[wasm_bindgen_test] -fn test_checked_sub() { - let now = Instant::now(); - - assert!(now.checked_sub(Duration::from_millis(1)).is_some()); - assert!(now - .checked_sub(Duration::new(u64::MAX, ONE_BILLION - 1)) - .is_none()); -} +extern crate wasm_bindgen_test;
+
+use instant::{Instant, SystemTime};
+use std::time::Duration;
+use wasm_bindgen_test::*;
+
+wasm_bindgen_test_configure!(run_in_browser);
+// run these tests using: wasm-pack test --chrome --headless -- --features wasm-bindgen
+
+#[wasm_bindgen_test]
+fn test_instant_now() {
+ let now = Instant::now();
+ #[cfg(feature = "inaccurate")]
+ while now.elapsed().as_millis() == 0 {}
+ #[cfg(not(feature = "inaccurate"))]
+ assert!(now.elapsed().as_nanos() > 0);
+}
+
+#[wasm_bindgen_test]
+fn test_duration() {
+ let now = Instant::now();
+ let one_sec = Duration::from_secs(1);
+ assert!(now.elapsed() < one_sec);
+}
+
+// Duration::new will overflow when you have u64::MAX seconds and one billion nanoseconds.
+// <https://doc.rust-lang.org/std/time/struct.Duration.html#method.new>
+const ONE_BILLION: u32 = 1_000_000_000;
+
+#[wasm_bindgen_test]
+fn test_checked_add() {
+ let now = Instant::now();
+
+ assert!(now.checked_add(Duration::from_millis(1)).is_some());
+ assert_eq!(
+ None,
+ now.checked_add(Duration::new(u64::MAX, ONE_BILLION - 1))
+ );
+}
+
+#[wasm_bindgen_test]
+fn test_checked_sub() {
+ let now = Instant::now();
+
+ assert!(now.checked_sub(Duration::from_millis(1)).is_some());
+ assert!(now
+ .checked_sub(Duration::new(u64::MAX, ONE_BILLION - 1))
+ .is_none());
+}
+
+#[wasm_bindgen_test]
+fn test_system_time() {
+ assert!(SystemTime::UNIX_EPOCH
+ .duration_since(SystemTime::now())
+ .is_err());
+}
+
|