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