Skip to main content

forma_ir/
lib.rs

1//! Forma Module IR: binary format definitions and parsers.
2//!
3//! This crate provides the core IR types and parsing logic that can be compiled
4//! to both native Rust and WebAssembly targets.
5
6#![allow(clippy::type_complexity)]
7
8pub mod format;
9pub mod parser;
10pub mod slot;
11pub mod walker;
12
13#[cfg(feature = "dump")]
14pub mod dump;
15
16// Re-exports for convenience
17pub use format::{
18    IrError, IrHeader, IslandEntry, IslandTrigger, Opcode, PropsMode, SectionDescriptor,
19    SectionTable, SlotEntry, SlotSource, SlotType, HEADER_SIZE, IR_VERSION, MAGIC,
20    SECTION_TABLE_SIZE,
21};
22pub use parser::{IrModule, IslandTableParsed, SlotTable, StringTable};
23pub use slot::{json_to_slot_value, SlotData, SlotValue};
24pub use walker::{walk_island, walk_to_html};
25
26#[cfg(feature = "wasm")]
27use wasm_bindgen::prelude::*;
28
29/// Full page render: parse IR bytes + JSON slots → HTML string.
30/// Panics on error (throws JS exception in WASM — client loader catches and falls back).
31#[cfg(feature = "wasm")]
32#[wasm_bindgen]
33pub fn render(ir_bytes: &[u8], slots_json: &str) -> String {
34    let module = parser::IrModule::parse(ir_bytes)
35        .unwrap_or_else(|e| panic!("IR parse: {e}"));
36    let slots = slot::SlotData::from_json(slots_json, &module)
37        .unwrap_or_else(|e| panic!("slots: {e}"));
38    walker::walk_to_html(&module, &slots)
39        .unwrap_or_else(|e| panic!("walk: {e}"))
40}
41
42/// Fragment render: parse IR bytes + JSON slots → island inner HTML.
43/// Panics on error (throws JS exception in WASM — client loader catches and falls back).
44#[cfg(feature = "wasm")]
45#[wasm_bindgen]
46pub fn render_island(ir_bytes: &[u8], slots_json: &str, island_id: u16) -> String {
47    let module = parser::IrModule::parse(ir_bytes)
48        .unwrap_or_else(|e| panic!("IR parse: {e}"));
49    let slots = slot::SlotData::from_json(slots_json, &module)
50        .unwrap_or_else(|e| panic!("slots: {e}"));
51    walker::walk_island(&module, &slots, island_id)
52        .unwrap_or_else(|e| panic!("walk island: {e}"))
53}