#![cfg(feature = "wasm")]
use wasm_bindgen::prelude::*;
use super::domain::check_domain;
use crate::error::{error_json, error_to_json};
use crate::serialization::types::{ModelMetadata, ModelType, SerializedModel};
use crate::serialization::FORMAT_VERSION;
fn iso_timestamp_wasm() -> String {
let date = js_sys::Date::new_0();
date.to_iso_string().into()
}
#[wasm_bindgen]
pub fn serialize_model(model_json: &str, model_type: &str, name: Option<String>) -> String {
if let Err(e) = check_domain() {
return error_to_json(&e);
}
let model_data: serde_json::Value = match serde_json::from_str(model_json) {
Ok(data) => data,
Err(e) => return error_json(&format!("Failed to parse model JSON: {}", e)),
};
let model_type_enum: ModelType = match model_type.parse() {
Ok(t) => t,
Err(_) => {
return error_json(&format!(
"Invalid model_type: '{}'. Must be one of: OLS, Ridge, Lasso, ElasticNet, WLS, LOESS",
model_type
))
}
};
let metadata = ModelMetadata {
format_version: FORMAT_VERSION.to_string(),
library_version: env!("CARGO_PKG_VERSION").to_string(),
model_type: model_type_enum,
created_at: iso_timestamp_wasm(),
name,
};
let serialized = SerializedModel::new(metadata, model_data);
match serde_json::to_string(&serialized) {
Ok(json) => json,
Err(e) => error_json(&format!("Failed to serialize model: {}", e)),
}
}
#[wasm_bindgen]
pub fn deserialize_model(json_string: &str) -> String {
if let Err(e) = check_domain() {
return error_to_json(&e);
}
let serialized: SerializedModel = match serde_json::from_str(json_string) {
Ok(model) => model,
Err(e) => return error_json(&format!("Failed to parse serialized model: {}", e)),
};
let file_version = &serialized.metadata.format_version;
let parts: Vec<&str> = file_version.split('.').collect();
let supported_parts: Vec<&str> = FORMAT_VERSION.split('.').collect();
if parts.len() >= 2 && supported_parts.len() >= 2 {
if let (Ok(file_major), Ok(supported_major)) = (
parts[0].parse::<u32>(),
supported_parts[0].parse::<u32>(),
) {
if file_major > supported_major {
return error_json(&format!(
"Incompatible format version: file is v{}, supported is v{}",
file_version, FORMAT_VERSION
));
}
}
}
match serde_json::to_string(&serialized.data) {
Ok(json) => json,
Err(e) => error_json(&format!("Failed to serialize model data: {}", e)),
}
}
#[wasm_bindgen]
pub fn get_model_metadata(json_string: &str) -> String {
if let Err(e) = check_domain() {
return error_to_json(&e);
}
let serialized: SerializedModel = match serde_json::from_str(json_string) {
Ok(model) => model,
Err(e) => return error_json(&format!("Failed to parse serialized model: {}", e)),
};
match serde_json::to_string(&serialized.metadata) {
Ok(json) => json,
Err(e) => error_json(&format!("Failed to serialize metadata: {}", e)),
}
}