#![cfg_attr(coverage_nightly, coverage(off))]
pub struct WasmLanguageDetector;
impl WasmLanguageDetector {
#[must_use]
pub fn new() -> Self {
Self
}
#[must_use]
pub fn is_assemblyscript(&self, content: &str) -> bool {
content.contains("@global")
|| content.contains("@inline")
|| content.contains("@external")
|| content.contains("i32")
|| content.contains("f64")
|| content.contains("memory.")
|| (content.contains("export") && content.contains("function"))
}
#[must_use]
pub fn is_wat(&self, content: &str) -> bool {
content.trim_start().starts_with('(')
&& (content.contains("module") || content.contains("func"))
}
#[must_use]
pub fn is_wasm_binary(&self, data: &[u8]) -> bool {
data.len() >= 8 && &data[0..4] == b"\0asm"
}
}
impl Default for WasmLanguageDetector {
fn default() -> Self {
Self::new()
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_detector_new() {
let detector = WasmLanguageDetector::new();
let _ = detector; }
#[test]
fn test_detector_default() {
let detector = WasmLanguageDetector::default();
let _ = detector;
}
#[test]
fn test_assemblyscript_detection() {
let detector = WasmLanguageDetector::new();
let as_content = "export function test(): i32 { return 42; }";
assert!(detector.is_assemblyscript(as_content));
let js_content = "function test() { return 42; }";
assert!(!detector.is_assemblyscript(js_content));
}
#[test]
fn test_assemblyscript_keywords() {
let detector = WasmLanguageDetector::new();
assert!(detector.is_assemblyscript("@global decorator"));
assert!(detector.is_assemblyscript("@inline function"));
assert!(detector.is_assemblyscript("@external import"));
assert!(detector.is_assemblyscript("let x: i32 = 0"));
assert!(detector.is_assemblyscript("let y: f64 = 0.0"));
assert!(detector.is_assemblyscript("memory.grow(1)"));
}
#[test]
fn test_wat_detection() {
let detector = WasmLanguageDetector::new();
let wat_content = "(module (func $test (result i32) i32.const 42))";
assert!(detector.is_wat(wat_content));
let js_content = "function test() { return 42; }";
assert!(!detector.is_wat(js_content));
}
#[test]
fn test_wat_with_whitespace() {
let detector = WasmLanguageDetector::new();
assert!(detector.is_wat(" (module)"));
assert!(detector.is_wat("\n(func)"));
assert!(detector.is_wat("\t(module (func))"));
}
#[test]
fn test_wat_empty_content() {
let detector = WasmLanguageDetector::new();
assert!(!detector.is_wat(""));
assert!(!detector.is_wat(" "));
}
#[test]
fn test_wasm_binary_detection() {
let detector = WasmLanguageDetector::new();
let wasm_data = b"\0asm\x01\x00\x00\x00";
assert!(detector.is_wasm_binary(wasm_data));
let text_data = b"not wasm binary";
assert!(!detector.is_wasm_binary(text_data));
}
#[test]
fn test_wasm_binary_too_short() {
let detector = WasmLanguageDetector::new();
assert!(!detector.is_wasm_binary(b""));
assert!(!detector.is_wasm_binary(b"\0as"));
assert!(!detector.is_wasm_binary(b"\0asm\x01\x00\x00")); }
#[test]
fn test_wasm_binary_wrong_magic() {
let detector = WasmLanguageDetector::new();
assert!(!detector.is_wasm_binary(b"\x01asm\x01\x00\x00\x00"));
assert!(!detector.is_wasm_binary(b"wasm\x01\x00\x00\x00"));
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod property_tests {
use proptest::prelude::*;
proptest! {
#[test]
fn basic_property_stability(_input in ".*") {
prop_assert!(true);
}
#[test]
fn module_consistency_check(_x in 0u32..1000) {
prop_assert!(_x < 1001);
}
}
}