forma_ir/lib.rs
1//! Forma Module IR: binary format definitions and parsers.
2//!
3//! This crate provides the IR parser and native server-side HTML walker.
4//!
5//! Fragment walking is internal; server consumers render the page with
6//! [`walk_to_html`] or [`walk_to_html_counted`]. Neither historical path is public:
7//!
8//! ```compile_fail
9//! use forma_ir::walk_island;
10//! ```
11//! ```compile_fail
12//! use forma_ir::walker::walk_island;
13//! ```
14//! ```compile_fail
15//! use forma_ir::walker::walk_island_with_limits;
16//! ```
17//! Test features do not expose a fragment renderer either:
18//! ```compile_fail
19//! use forma_ir::parser::test_helpers::walk_island;
20//! ```
21
22// README.md and SECURITY.md both promise "Zero `unsafe` blocks". This is what
23// makes that a compiler-enforced property of the shipped library rather than a
24// claim. It is crate-root rather than a `[lints]` entry because `[lints]`
25// covers every target in the package, and the allocation-counting harness in
26// `tests/list_scaling.rs` must implement `GlobalAlloc` — a separate crate, not
27// code that ships.
28#![forbid(unsafe_code)]
29#![allow(clippy::type_complexity)]
30// No `unwrap`, `expect` or `panic!` in the code that ships (DR-12, SR44): a
31// walk returns its failure, it does not take the request down. Tests may.
32#![cfg_attr(
33 not(test),
34 deny(clippy::unwrap_used, clippy::expect_used, clippy::panic)
35)]
36
37mod contracts;
38/// On-disk FMIR layout: header, section table, opcodes, and the table entry
39/// types. See `docs/FMIR-FORMAT.md` for the stability contract.
40pub mod format;
41/// Canonical row identity for keyed lists (FORMA-181): the key domain, the
42/// path read and the text written as `data-forma-key`. Crate-private; the
43/// shared vectors are `tests/fixtures/parity/keys.json`.
44mod keys;
45/// Bounds-checked parsing and one-shot structural validation of an FMIR file.
46pub mod parser;
47/// Derived page contracts, schema comparison and checked value encoding.
48pub mod props;
49/// Typed props schema, key paths and source positions carried by FMIR v3.
50pub mod schema;
51/// Runtime slot values and the dense `SlotData` a page handler populates.
52pub mod slot;
53/// Rule-1 text normalization shared by the walker's ordinary text and
54/// attribute writes (FORMA-182). Crate-private: not part of the API.
55mod text;
56/// The SSR walker: opcode stream plus slot values in, HTML out.
57pub mod walker;
58
59/// INTERNAL, behind the `__fault-injection` feature: the stand-in component
60/// that panics, for SR44's tests. Never in a build that ships.
61#[cfg(any(test, feature = "__fault-injection"))]
62#[doc(hidden)]
63pub mod fault_injection {
64 /// A DYN_TEXT value equal to this makes the walk panic, but only inside
65 /// [`crate::walker::walk_to_html_counted`], which catches it: the
66 /// uncaught `walk_to_html` path never arms the trigger. It lets a test
67 /// show that a panic inside the walk becomes an error naming its island,
68 /// and that the next render works. Compiled only for this crate's tests
69 /// and under the internal `__fault-injection` feature, which only the two
70 /// crates' own dev-dependencies enable; `test-helpers` does not.
71 pub const FAULT_TRIGGER: &str = "\u{0}forma-test-fault\u{0}";
72}
73
74/// Internal property-test adapters; absent from ordinary dependency builds.
75#[cfg(any(test, feature = "__fuzzing"))]
76#[doc(hidden)]
77pub mod fuzz_support;
78
79/// Human-readable text dump of a module, for debugging and diffing.
80#[cfg(feature = "dump")]
81pub mod dump;
82
83/// Derive a named props struct or unit enum.
84pub use forma_ir_derive::PageProps;
85pub use props::PageProps;
86
87// Re-exports for convenience
88pub use format::{
89 IrError, IrHeader, IslandEntry, IslandTrigger, ListKeyReason, ListKeyViolation, Opcode,
90 SectionDescriptor, SectionTable, SlotEntry, SlotSource, SlotType, HEADER_SIZE, IR_VERSION,
91 SECTION_ENTRY_SIZE, SIGNATURE, TABLE_PREFIX_SIZE,
92};
93pub use parser::{IrModule, IslandTableParsed, SlotTable, StringTable};
94pub use slot::{json_to_slot_value, SlotData, SlotValue};
95pub use walker::{
96 walk_to_html, walk_to_html_counted, walk_to_html_with_limits, IslandState, WalkCounts,
97 WalkFailure, WalkLimits, WalkOutput, DEFAULT_MAX_LIST_ITERATIONS, DEFAULT_MAX_OUTPUT_BYTES,
98};
99
100// The combined page/fragment corpus has private access to the internal walker.
101// No feature exports a fragment renderer to consumers.
102#[cfg(test)]
103mod js_emitter_contract;