modality_lang/
wasm.rs

1use wasm_bindgen::prelude::*;
2use wasm_bindgen::JsValue;
3use crate::ast::{Model, PropertySign, Formula};
4use crate::lalrpop_parser::{parse_file_lalrpop, parse_content_lalrpop, parse_all_models_lalrpop, parse_all_models_content_lalrpop, parse_all_formulas_content_lalrpop};
5use crate::mermaid::{generate_mermaid_diagram, generate_mermaid_diagrams, generate_mermaid_diagram_with_styling, generate_mermaid_diagram_with_state};
6use crate::model_checker::{ModelChecker, State, ModelCheckResult};
7use serde_json;
8
9#[wasm_bindgen]
10pub struct ModalityParser {
11    // This struct can hold any state if needed in the future
12}
13
14#[wasm_bindgen]
15impl ModalityParser {
16    #[wasm_bindgen(constructor)]
17    pub fn new() -> ModalityParser {
18        ModalityParser { }
19    }
20
21    /// Parse a model from a string
22    pub fn parse_model(&self, content: &str) -> Result<JsValue, JsValue> {
23        let model = parse_content_lalrpop(content)
24            .map_err(|e| JsValue::from_str(&e))?;
25        wasm_bindgen::JsValue::from_serde(&model).map_err(|e| JsValue::from_str(&format!("Serde error: {}", e)))
26    }
27
28    /// Parse all models from a string
29    pub fn parse_all_models(&self, content: &str) -> Result<JsValue, JsValue> {
30        let models = parse_all_models_content_lalrpop(content)
31            .map_err(|e| JsValue::from_str(&e))?;
32        wasm_bindgen::JsValue::from_serde(&models).map_err(|e| JsValue::from_str(&format!("Serde error: {}", e)))
33    }
34
35    /// Generate Mermaid diagram from a model JSON string
36    pub fn generate_mermaid(&self, model_json: &str) -> Result<String, JsValue> {
37        let model: Model = serde_json::from_str(model_json)
38            .map_err(|e| JsValue::from_str(&format!("JSON parse error: {}", e)))?;
39        Ok(generate_mermaid_diagram(&model))
40    }
41
42    /// Generate Mermaid diagram with styling from a model JSON string
43    pub fn generate_mermaid_styled(&self, model_json: &str) -> Result<String, JsValue> {
44        let model: Model = serde_json::from_str(model_json)
45            .map_err(|e| JsValue::from_str(&format!("JSON parse error: {}", e)))?;
46        Ok(generate_mermaid_diagram_with_styling(&model))
47    }
48
49    /// Generate Mermaid diagram with current state highlighting from a model JSON string
50    pub fn generate_mermaid_with_state(&self, model_json: &str) -> Result<String, JsValue> {
51        let model: Model = serde_json::from_str(model_json)
52            .map_err(|e| JsValue::from_str(&format!("JSON parse error: {}", e)))?;
53        Ok(generate_mermaid_diagram_with_state(&model))
54    }
55
56    /// Parse formulas from a string
57    pub fn parse_formulas(&self, content: &str) -> Result<JsValue, JsValue> {
58        let formulas = parse_all_formulas_content_lalrpop(content)
59            .map_err(|e| JsValue::from_str(&e))?;
60        wasm_bindgen::JsValue::from_serde(&formulas).map_err(|e| JsValue::from_str(&format!("Serde error: {}", e)))
61    }
62
63    /// Check a formula against a model (per-graph requirement)
64    pub fn check_formula(&self, model_json: &str, formula_json: &str) -> Result<JsValue, JsValue> {
65        let model: Model = serde_json::from_str(model_json)
66            .map_err(|e| JsValue::from_str(&format!("Model JSON parse error: {}", e)))?;
67        let formula: Formula = serde_json::from_str(formula_json)
68            .map_err(|e| JsValue::from_str(&format!("Formula JSON parse error: {}", e)))?;
69        
70        let checker = ModelChecker::new(model);
71        let result = checker.check_formula(&formula);
72        wasm_bindgen::JsValue::from_serde(&result).map_err(|e| JsValue::from_str(&format!("Serde error: {}", e)))
73    }
74
75    /// Check a formula against a model (any-state requirement)
76    pub fn check_formula_any_state(&self, model_json: &str, formula_json: &str) -> Result<JsValue, JsValue> {
77        let model: Model = serde_json::from_str(model_json)
78            .map_err(|e| JsValue::from_str(&format!("Model JSON parse error: {}", e)))?;
79        let formula: Formula = serde_json::from_str(formula_json)
80            .map_err(|e| JsValue::from_str(&format!("Formula JSON parse error: {}", e)))?;
81        
82        let checker = ModelChecker::new(model);
83        let result = checker.check_formula_any_state(&formula);
84        wasm_bindgen::JsValue::from_serde(&result).map_err(|e| JsValue::from_str(&format!("Serde error: {}", e)))
85    }
86}
87
88/// Standalone WASM functions
89#[wasm_bindgen]
90pub fn parse_model(content: &str) -> Result<JsValue, JsValue> {
91    let model = parse_content_lalrpop(content)
92        .map_err(|e| JsValue::from_str(&e))?;
93    wasm_bindgen::JsValue::from_serde(&model).map_err(|e| JsValue::from_str(&format!("Serde error: {}", e)))
94}
95
96#[wasm_bindgen]
97pub fn parse_all_models(content: &str) -> Result<JsValue, JsValue> {
98    let models = parse_all_models_content_lalrpop(content)
99        .map_err(|e| JsValue::from_str(&e))?;
100    wasm_bindgen::JsValue::from_serde(&models).map_err(|e| JsValue::from_str(&format!("Serde error: {}", e)))
101}
102
103#[wasm_bindgen]
104pub fn generate_mermaid(model_json: &str) -> Result<String, JsValue> {
105    let model: Model = serde_json::from_str(model_json)
106        .map_err(|e| JsValue::from_str(&format!("JSON parse error: {}", e)))?;
107    Ok(generate_mermaid_diagram(&model))
108}
109
110#[wasm_bindgen]
111pub fn generate_mermaid_styled(model_json: &str) -> Result<String, JsValue> {
112    let model: Model = serde_json::from_str(model_json)
113        .map_err(|e| JsValue::from_str(&format!("JSON parse error: {}", e)))?;
114    Ok(generate_mermaid_diagram_with_styling(&model))
115}
116
117#[wasm_bindgen]
118pub fn generate_mermaid_with_state(model_json: &str) -> Result<String, JsValue> {
119    let model: Model = serde_json::from_str(model_json)
120        .map_err(|e| JsValue::from_str(&format!("JSON parse error: {}", e)))?;
121    Ok(generate_mermaid_diagram_with_state(&model))
122}
123
124#[wasm_bindgen]
125pub fn parse_formulas(content: &str) -> Result<JsValue, JsValue> {
126    let formulas = parse_all_formulas_content_lalrpop(content)
127        .map_err(|e| JsValue::from_str(&e))?;
128    wasm_bindgen::JsValue::from_serde(&formulas).map_err(|e| JsValue::from_str(&format!("Serde error: {}", e)))
129}
130
131#[wasm_bindgen]
132pub fn check_formula(model_json: &str, formula_json: &str) -> Result<JsValue, JsValue> {
133    let model: Model = serde_json::from_str(model_json)
134        .map_err(|e| JsValue::from_str(&format!("Model JSON parse error: {}", e)))?;
135    let formula: Formula = serde_json::from_str(formula_json)
136        .map_err(|e| JsValue::from_str(&format!("Formula JSON parse error: {}", e)))?;
137    
138    let checker = ModelChecker::new(model);
139    let result = checker.check_formula(&formula);
140    wasm_bindgen::JsValue::from_serde(&result).map_err(|e| JsValue::from_str(&format!("Serde error: {}", e)))
141}
142
143#[wasm_bindgen]
144pub fn check_formula_any_state(model_json: &str, formula_json: &str) -> Result<JsValue, JsValue> {
145    let model: Model = serde_json::from_str(model_json)
146        .map_err(|e| JsValue::from_str(&format!("Model JSON parse error: {}", e)))?;
147    let formula: Formula = serde_json::from_str(formula_json)
148        .map_err(|e| JsValue::from_str(&format!("Formula JSON parse error: {}", e)))?;
149    
150    let checker = ModelChecker::new(model);
151    let result = checker.check_formula_any_state(&formula);
152    wasm_bindgen::JsValue::from_serde(&result).map_err(|e| JsValue::from_str(&format!("Serde error: {}", e)))
153}