Skip to main content

ipfrs_core/
wasm_compat.rs

1//! wasm32 compatibility layer for ipfrs-core.
2//!
3//! This module provides documentation and helpers for wasm32 targets.
4//! Most of ipfrs-core is already wasm-compatible since it uses only
5//! pure-Rust data structures.
6
7/// Whether the current target is wasm32.
8pub const IS_WASM32: bool = cfg!(target_arch = "wasm32");
9
10/// A platform-independent timestamp in milliseconds.
11///
12/// On wasm32 this returns a stub value (0). For real browser timestamps,
13/// use `js_sys::Date::now()` via the `wasm-bindgen` / `js-sys` crates.
14/// On native targets this delegates to [`std::time::SystemTime`].
15pub struct PlatformTime;
16
17impl PlatformTime {
18    /// Returns current time in milliseconds since Unix epoch.
19    ///
20    /// * On wasm32: returns `0` (stub — production builds should use `js_sys::Date::now()`).
21    /// * On native: uses [`std::time::SystemTime`].
22    pub fn now_ms() -> u64 {
23        #[cfg(not(target_arch = "wasm32"))]
24        {
25            use std::time::{SystemTime, UNIX_EPOCH};
26            SystemTime::now()
27                .duration_since(UNIX_EPOCH)
28                .map(|d| d.as_millis() as u64)
29                .unwrap_or(0)
30        }
31        #[cfg(target_arch = "wasm32")]
32        {
33            // Stub: real wasm builds should use `js_sys::Date::now() as u64`
34            // via the `js` feature of `getrandom` / `js-sys` crate.
35            0u64
36        }
37    }
38}
39
40/// Capabilities available on the current compile target.
41pub struct TargetCapabilities;
42
43impl TargetCapabilities {
44    /// Returns `true` when the filesystem APIs (`std::fs`) are available.
45    pub fn has_filesystem() -> bool {
46        !IS_WASM32
47    }
48
49    /// Returns `true` when OS threads are available.
50    pub fn has_threads() -> bool {
51        !IS_WASM32
52    }
53
54    /// Returns `true` when native network sockets (`std::net`) are available.
55    pub fn has_network_sockets() -> bool {
56        !IS_WASM32
57    }
58
59    /// Returns `true` when running inside a browser (wasm32 target).
60    pub fn is_browser() -> bool {
61        IS_WASM32
62    }
63}
64
65#[cfg(test)]
66mod tests {
67    use super::*;
68
69    #[test]
70    fn test_is_wasm32_const_false_on_native() {
71        // This test only runs on non-wasm32 targets.
72        #[cfg(not(target_arch = "wasm32"))]
73        const {
74            assert!(!IS_WASM32)
75        };
76    }
77
78    #[test]
79    fn test_platform_time_now_ms_nonzero() {
80        #[cfg(not(target_arch = "wasm32"))]
81        {
82            let ms = PlatformTime::now_ms();
83            assert!(
84                ms > 0,
85                "expected non-zero timestamp on native target, got {ms}"
86            );
87        }
88    }
89
90    #[test]
91    fn test_target_capabilities_native() {
92        #[cfg(not(target_arch = "wasm32"))]
93        {
94            assert!(TargetCapabilities::has_filesystem());
95            assert!(TargetCapabilities::has_threads());
96            assert!(TargetCapabilities::has_network_sockets());
97        }
98    }
99
100    #[test]
101    fn test_is_browser_false_on_native() {
102        #[cfg(not(target_arch = "wasm32"))]
103        assert!(!TargetCapabilities::is_browser());
104    }
105}