//! WASM-specific utilities (enabled with "wasm" feature) #[cfg(target_arch = "wasm32")] use wasm_bindgen::prelude::*; #[cfg(target_arch = "wasm32")] use web_sys::{console, window, Window, Document, HtmlElement}; /// Console logging utilities for WASM pub mod console { #[cfg(target_arch = "wasm32")] use super::*; /// Log message to browser console #[cfg(target_arch = "wasm32")] pub fn log(message: &str) { console::log_1(&message.into()); } /// Log error to browser console #[cfg(target_arch = "wasm32")] pub fn error(message: &str) { console::error_1(&message.into()); } /// Log warning to browser console #[cfg(target_arch = "wasm32")] pub fn warn(message: &str) { console::warn_1(&message.into()); } /// No-op implementations for non-WASM targets #[cfg(not(target_arch = "wasm32"))] pub fn log(_message: &str) {} #[cfg(not(target_arch = "wasm32"))] pub fn error(_message: &str) {} #[cfg(not(target_arch = "wasm32"))] pub fn warn(_message: &str) {} } /// DOM manipulation utilities for WASM pub mod dom { #[cfg(target_arch = "wasm32")] use super::*; /// Get the window object #[cfg(target_arch = "wasm32")] pub fn window() -> Result { web_sys::window().ok_or_else(|| JsValue::from_str("No window object")) } /// Get the document object #[cfg(target_arch = "wasm32")] pub fn document() -> Result { window()? .document() .ok_or_else(|| JsValue::from_str("No document object")) } /// Get element by ID #[cfg(target_arch = "wasm32")] pub fn get_element_by_id(id: &str) -> Result, JsValue> { let doc = document()?; Ok(doc .get_element_by_id(id) .and_then(|elem| elem.dyn_into::().ok())) } /// Set element text content #[cfg(target_arch = "wasm32")] pub fn set_text_content(element: &HtmlElement, content: &str) { element.set_text_content(Some(content)); } /// Set element inner HTML #[cfg(target_arch = "wasm32")] pub fn set_inner_html(element: &HtmlElement, html: &str) { element.set_inner_html(html); } /// No-op implementations for non-WASM targets #[cfg(not(target_arch = "wasm32"))] pub fn window() -> Result<(), &'static str> { Err("Not available on non-WASM targets") } #[cfg(not(target_arch = "wasm32"))] pub fn document() -> Result<(), &'static str> { Err("Not available on non-WASM targets") } } /// Local storage utilities for WASM pub mod storage { #[cfg(target_arch = "wasm32")] use super::*; /// Get item from local storage #[cfg(target_arch = "wasm32")] pub fn get_item(key: &str) -> Result, JsValue> { let storage = window()? .local_storage()? .ok_or_else(|| JsValue::from_str("No localStorage"))?; storage.get_item(key) } /// Set item in local storage #[cfg(target_arch = "wasm32")] pub fn set_item(key: &str, value: &str) -> Result<(), JsValue> { let storage = window()? .local_storage()? .ok_or_else(|| JsValue::from_str("No localStorage"))?; storage.set_item(key, value) } /// Remove item from local storage #[cfg(target_arch = "wasm32")] pub fn remove_item(key: &str) -> Result<(), JsValue> { let storage = window()? .local_storage()? .ok_or_else(|| JsValue::from_str("No localStorage"))?; storage.remove_item(key) } /// No-op implementations for non-WASM targets #[cfg(not(target_arch = "wasm32"))] pub fn get_item(_key: &str) -> Result, &'static str> { Err("Not available on non-WASM targets") } #[cfg(not(target_arch = "wasm32"))] pub fn set_item(_key: &str, _value: &str) -> Result<(), &'static str> { Err("Not available on non-WASM targets") } #[cfg(not(target_arch = "wasm32"))] pub fn remove_item(_key: &str) -> Result<(), &'static str> { Err("Not available on non-WASM targets") } } /// HTTP utilities for WASM pub mod http { #[cfg(target_arch = "wasm32")] use super::*; #[cfg(target_arch = "wasm32")] use reqwasm::http::Request; /// Simple GET request #[cfg(target_arch = "wasm32")] pub async fn get(url: &str) -> Result { let response = Request::get(url).send().await?; response.text().await } /// Simple POST request with JSON body #[cfg(target_arch = "wasm32")] pub async fn post_json(url: &str, body: &str) -> Result { let response = Request::post(url) .header("Content-Type", "application/json") .body(body) .send() .await?; response.text().await } /// No-op implementations for non-WASM targets #[cfg(not(target_arch = "wasm32"))] pub async fn get(_url: &str) -> Result { Err("Not available on non-WASM targets") } #[cfg(not(target_arch = "wasm32"))] pub async fn post_json(_url: &str, _body: &str) -> Result { Err("Not available on non-WASM targets") } } #[cfg(test)] mod tests { use super::*; #[test] fn test_console_logging() { // These are no-ops on non-WASM, but should not panic console::log("Test message"); console::error("Test error"); console::warn("Test warning"); } #[test] fn test_dom_functions() { // These should return errors on non-WASM targets let result = dom::window(); assert!(result.is_err()); let result = dom::document(); assert!(result.is_err()); } #[test] fn test_storage_functions() { // These should return errors on non-WASM targets let result = storage::get_item("test"); assert!(result.is_err()); let result = storage::set_item("test", "value"); assert!(result.is_err()); let result = storage::remove_item("test"); assert!(result.is_err()); } #[tokio::test] async fn test_http_functions() { // These should return errors on non-WASM targets let result = http::get("https://example.com").await; assert!(result.is_err()); let result = http::post_json("https://example.com", "{}").await; assert!(result.is_err()); } }