use crate::error::NumRs2Error;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn set_panic_hook() {
#[cfg(feature = "wasm")]
{
console_error_panic_hook::set_once();
}
}
#[wasm_bindgen]
pub fn version() -> String {
env!("CARGO_PKG_VERSION").to_string()
}
#[wasm_bindgen]
pub fn library_name() -> String {
"numrs2".to_string()
}
#[wasm_bindgen]
pub fn library_info() -> String {
format!(
r#"{{"name":"{}","version":"{}","description":"{}","features":{}}}"#,
library_name(),
version(),
"NumRS2: High-Performance Numerical Computing in Rust for WebAssembly",
get_feature_flags()
)
}
fn get_feature_flags() -> String {
let mut features = Vec::new();
#[cfg(feature = "wasm")]
features.push("wasm");
#[cfg(feature = "lapack")]
features.push("lapack");
#[cfg(feature = "gpu")]
features.push("gpu");
#[cfg(feature = "python")]
features.push("python");
#[cfg(feature = "arrow")]
features.push("arrow");
#[cfg(feature = "matrix_decomp")]
features.push("matrix_decomp");
format!("{:?}", features)
}
#[wasm_bindgen]
pub fn log(message: &str) {
web_sys::console::log_1(&JsValue::from_str(message));
}
#[wasm_bindgen]
pub fn warn(message: &str) {
web_sys::console::warn_1(&JsValue::from_str(message));
}
#[wasm_bindgen]
pub fn error(message: &str) {
web_sys::console::error_1(&JsValue::from_str(message));
}
#[wasm_bindgen]
pub fn memory_usage() -> usize {
let memory_value = wasm_bindgen::memory();
let array_buffer: js_sys::ArrayBuffer = memory_value.unchecked_into();
array_buffer.byte_length() as usize
}
#[wasm_bindgen]
pub fn has_simd_support() -> bool {
#[cfg(target_feature = "simd128")]
{
true
}
#[cfg(not(target_feature = "simd128"))]
{
false
}
}
#[wasm_bindgen]
pub fn has_threads_support() -> bool {
#[cfg(target_feature = "atomics")]
{
true
}
#[cfg(not(target_feature = "atomics"))]
{
false
}
}
pub(crate) fn error_to_js(error: NumRs2Error) -> JsValue {
JsValue::from_str(&format!("NumRS2 Error: {}", error))
}
#[wasm_bindgen]
pub struct PerfTimer {
start_time: f64,
}
impl Default for PerfTimer {
fn default() -> Self {
Self::new()
}
}
#[wasm_bindgen]
impl PerfTimer {
#[wasm_bindgen(constructor)]
pub fn new() -> PerfTimer {
let start_time = web_sys::window()
.and_then(|w| w.performance())
.map(|p| p.now())
.unwrap_or(0.0);
PerfTimer { start_time }
}
#[wasm_bindgen]
pub fn elapsed(&self) -> f64 {
web_sys::window()
.and_then(|w| w.performance())
.map(|p| p.now() - self.start_time)
.unwrap_or(0.0)
}
#[wasm_bindgen]
pub fn reset(&mut self) {
self.start_time = web_sys::window()
.and_then(|w: web_sys::Window| w.performance())
.map(|p: web_sys::Performance| p.now())
.unwrap_or(0.0);
}
}
#[cfg(feature = "wasm")]
#[global_allocator]
static ALLOC: dlmalloc::GlobalDlmalloc = dlmalloc::GlobalDlmalloc;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_version() {
let ver = version();
assert!(!ver.is_empty());
assert!(ver.contains("0.3"));
}
#[test]
fn test_library_name() {
assert_eq!(library_name(), "numrs2");
}
#[test]
fn test_library_info() {
let info = library_info();
assert!(info.contains("numrs2"));
assert!(info.contains("version"));
}
#[test]
fn test_feature_flags() {
let flags = get_feature_flags();
assert!(flags.contains("wasm"));
}
#[test]
fn test_simd_support() {
let _has_simd = has_simd_support();
}
#[test]
fn test_threads_support() {
let _has_threads = has_threads_support();
}
}