summaryrefslogtreecommitdiffstats
path: root/third_party/rust/instant/src/wasm.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/instant/src/wasm.rs
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/instant/src/wasm.rs')
-rw-r--r--third_party/rust/instant/src/wasm.rs240
1 files changed, 240 insertions, 0 deletions
diff --git a/third_party/rust/instant/src/wasm.rs b/third_party/rust/instant/src/wasm.rs
new file mode 100644
index 0000000000..f11b82a703
--- /dev/null
+++ b/third_party/rust/instant/src/wasm.rs
@@ -0,0 +1,240 @@
+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;
+ }
+}