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}