mst_parser/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]
2/* src/lib.rs */
3
4#![deny(missing_docs)]
5#![allow(clippy::collapsible_if)]
6
7//! # mst-parser
8//!
9//! A zero-dependency, mustache-style template parser supporting nested variables.
10//!
11//! This crate provides a recursive descent parser for `{{variable}}` style syntax.
12//! It produces an Abstract Syntax Tree (AST) but does *not* perform any rendering or substitution.
13//!
14//! ## Features
15//!
16//! * **Nested Variables**: Supports `{{ key.{{subsection}} }}` syntax.
17//! * **Safety**: Configurable limits on recursion depth and node count to prevent malicious inputs.
18//! * **no_std**: Compatible with `#![no_std]` environments (requires `alloc`).
19//! * **Diagnostics**: Optional `tracing` integration for parser debugging.
20//!
21//! ## Example
22//!
23//! ```rust
24//! use mst_parser::{parse, Limits, Node, Parser};
25//!
26//! let input = "Hello {{user.{{attr}}}}!";
27//! // Use default limits
28//! let nodes = parse(input).unwrap();
29//!
30//! assert_eq!(nodes.len(), 3);
31//! match &nodes[1] {
32//! Node::Variable { parts } => {
33//! // parts represents: "user.", {{attr}}
34//! assert_eq!(parts.len(), 2);
35//! }
36//! _ => panic!("Expected variable"),
37//! }
38//!
39//! // Or with custom limits
40//! let limits = Limits { max_depth: 2, ..Limits::default() };
41//! let parser = Parser::new(limits);
42//! let nodes = parser.parse(input).unwrap();
43//! ```
44
45extern crate alloc;
46
47mod ast;
48mod error;
49mod parser;
50
51pub use ast::{Limits, Node};
52pub use error::Error;
53pub use parser::{parse, Parser};