use crate::wasm::common::error::{WasmError, WasmResult};
use crate::wasm::common::validation::WasmValidation;
use crate::wasm::tensor::WasmTensor;
use js_sys::Array;
use wasm_bindgen::prelude::*;
pub trait WasmOperation {
fn name(&self) -> String;
fn version(&self) -> String {
crate::wasm::common::WasmVersion::module_version(&self.name())
}
fn validate_params(&self) -> WasmResult<()> {
Ok(())
}
}
pub trait WasmTransform: WasmOperation {
fn apply(&self, tensor: &WasmTensor) -> WasmResult<WasmTensor>;
fn can_apply(&self, tensor: &WasmTensor) -> WasmResult<()> {
tensor.validate_non_empty()
}
fn get_params_json(&self) -> String {
format!("{{\"name\":\"{}\"}}", self.name())
}
}
pub trait WasmAnalyzer: WasmOperation {
fn analyze(&self, tensor: &WasmTensor) -> WasmResult<String>;
fn analysis_type(&self) -> &'static str;
fn can_analyze(&self, tensor: &WasmTensor) -> WasmResult<()> {
tensor.validate_non_empty()
}
}
pub trait WasmDetector: WasmOperation {
fn detect(&mut self, tensor: &WasmTensor) -> WasmResult<Array>;
fn detection_type(&self) -> &'static str;
fn threshold(&self) -> f32;
fn set_threshold(&mut self, threshold: f32) -> WasmResult<()>;
fn get_config(&self) -> String {
format!(
"{{\"type\":\"{}\",\"threshold\":{}}}",
self.detection_type(),
self.threshold()
)
}
fn reset(&mut self);
fn update_params(&mut self, params: &str) -> WasmResult<()> {
Ok(())
}
}
pub trait WasmMathOperation: WasmOperation {
fn apply_unary(&self, tensor: &WasmTensor) -> WasmResult<WasmTensor>;
fn apply_binary(&self, left: &WasmTensor, right: &WasmTensor) -> WasmResult<WasmTensor> {
Err(WasmError::invalid_param(
"operation",
self.name(),
"binary operation not supported",
))
}
fn supports_operation(&self, operation: &str) -> bool;
fn operation_complexity(&self, operation: &str) -> u32;
fn supports_inplace(&self) -> bool {
false
}
}
pub trait WasmStatistical: WasmOperation {
fn calculate_stats(&self, tensor: &WasmTensor) -> WasmResult<String>;
fn get_summary(&self, tensor: &WasmTensor) -> WasmResult<String> {
self.calculate_stats(tensor)
}
fn statistical_summary(&self, tensor: &WasmTensor) -> WasmResult<String> {
self.calculate_stats(tensor)
}
fn supports_statistical_operation(&self, operation: &str) -> bool;
fn has_sufficient_data(&self, tensor: &WasmTensor) -> bool {
!tensor.data().is_empty()
}
}
pub trait WasmImageOperation: WasmTransform {
fn validate_image(&self, tensor: &WasmTensor) -> WasmResult<(usize, usize)> {
crate::wasm::common::WasmValidator::validate_image_tensor(tensor)
}
fn output_dimensions(&self, input_dims: (usize, usize)) -> (usize, usize);
fn preserves_channels(&self) -> bool {
true
}
}
pub trait WasmQualityAssessment: WasmAnalyzer {
fn quality_score(&self, tensor: &WasmTensor) -> WasmResult<f32>;
fn quality_threshold(&self) -> f32;
fn meets_quality_threshold(&self, tensor: &WasmTensor) -> WasmResult<bool> {
let score = self.quality_score(tensor)?;
Ok(score >= self.quality_threshold())
}
fn detailed_report(&self, tensor: &WasmTensor) -> WasmResult<String> {
self.analyze(tensor)
}
}
pub trait WasmVersioned {
fn module_version() -> String;
fn compatibility_version() -> String {
Self::module_version()
}
fn is_compatible_with(version: &str) -> bool {
version == &Self::module_version()
}
}
#[macro_export]
macro_rules! impl_wasm_operation {
($type:ty, $name:expr) => {
impl WasmOperation for $type {
fn name(&self) -> String {
$name.to_string()
}
}
};
}
#[macro_export]
macro_rules! impl_wasm_versioned {
($type:ty, $module_name:expr) => {
impl WasmVersioned for $type {
fn module_version() -> String {
crate::wasm::common::WasmVersion::module_version($module_name)
}
}
};
}