pub fn compile_safe_with_depth(
layout: Box<Layout>,
max_depth: usize,
) -> Result<Box<Doc>, CompilerError>Expand description
Compiles a layout with custom recursion depth limit and error handling (configurable safe path)
This function provides the most flexible compilation approach, allowing fine-grained control over stack overflow protection by configuring the maximum recursion depth. It’s useful when you know the characteristics of your layouts and want to optimize for either safety (lower limits) or performance with deeply nested structures (higher limits).
The function uses the same 10-pass compilation pipeline as compile() and compile_safe()
but allows customization of the recursion depth threshold that triggers stack overflow protection.
§Arguments
layout- The input layout tree to compile. Can handle arbitrarily complex structures within the recursion depth limit.max_depth- Maximum recursion depth before stack overflow protection activates. Must be greater than 0. Common values:- Conservative (1,000-5,000): Safe for resource-constrained environments
- Default (10,000): Good balance of safety and capability
- Aggressive (20,000+): For known deep layouts with sufficient stack space
§Returns
Ok(Box<Doc>)- Successfully compiled document ready for renderingErr(CompilerError)- Compilation failed with detailed error information
§Error Conditions
This function can return several types of errors:
CompilerError::InvalidInput- Ifmax_depthis 0 or other parameter validation failsCompilerError::StackOverflow- If layout nesting exceeds the specifiedmax_depthCompilerError::AllocationFailed- If memory allocation fails during any compilation pass
§Performance Notes
- Time: O(n) where n is the number of layout nodes
- Memory: Uses 10 temporary bump allocators during compilation
- Stack Usage: Proportional to layout nesting depth, limited by
max_depth - Depth Tracking: Minimal overhead for recursion depth counting
- Optimal Use: When you need precise control over compilation resource usage
§Choosing Recursion Depth Limits
The optimal max_depth depends on your use case:
- Web Services: 1,000-5,000 (protect against malicious input)
- Desktop Applications: 10,000-15,000 (balance safety and capability)
- Code Generators: 20,000+ (handle deeply nested syntax trees)
- Embedded Systems: 500-2,000 (limited stack space)
§Examples
§Conservative Compilation for Web Services
use typeset::{compile_safe_with_depth, render, text};
fn compile_user_input(content: String) -> Result<String, String> {
let layout = text(content);
// Use conservative depth limit for untrusted input
match compile_safe_with_depth(layout, 1000) {
Ok(doc) => Ok(render(doc, 2, 80)),
Err(e) => Err(format!("Compilation failed: {}", e)),
}
}§High-Performance Compilation for Code Generation
use typeset::{compile_safe_with_depth, render, text, comp, nest};
fn compile_syntax_tree(depth: usize) -> Result<String, String> {
// Build a deeply nested layout representing a syntax tree
let mut layout = text("root".to_string());
for i in 0..depth {
layout = nest(comp(
layout,
text(format!("node_{}", i)),
false, false
));
}
// Use high depth limit for known deep structures
match compile_safe_with_depth(layout, 25000) {
Ok(doc) => Ok(render(doc, 4, 120)),
Err(e) => Err(format!("Failed to compile deep tree: {}", e)),
}
}§Resource-Constrained Environment
use typeset::{compile_safe_with_depth, render, text, CompilerError};
fn compile_with_limited_stack(layout: Box<typeset::Layout>) -> Result<String, String> {
// Use very conservative limit for embedded systems
match compile_safe_with_depth(layout, 500) {
Ok(doc) => Ok(render(doc, 2, 40)),
Err(CompilerError::StackOverflow { depth, max_depth }) => {
Err(format!(
"Layout too deep for this system: {} levels (max: {})",
depth, max_depth
))
}
Err(e) => Err(format!("Compilation error: {}", e)),
}
}§Adaptive Depth Strategy
use typeset::{compile_safe_with_depth, render, text, CompilerError};
fn compile_with_fallback(layout: Box<typeset::Layout>) -> Result<String, String> {
// Try aggressive first, fall back to conservative
let depths = [20000, 10000, 5000, 1000];
for &depth in &depths {
match compile_safe_with_depth(layout.clone(), depth) {
Ok(doc) => return Ok(render(doc, 2, 80)),
Err(CompilerError::StackOverflow { .. }) => continue,
Err(e) => return Err(format!("Non-depth error: {}", e)),
}
}
Err("Layout too complex even with minimum depth limit".to_string())
}§Parameter Validation
use typeset::{compile_safe_with_depth, text, CompilerError};
let layout = text("test".to_string());
// This will fail with InvalidInput error
match compile_safe_with_depth(layout, 0) {
Err(CompilerError::InvalidInput(msg)) => {
println!("Expected error: {}", msg);
}
_ => panic!("Should have failed with InvalidInput"),
}§See Also
compile()- Fast compilation that panics on errorscompile_safe()- Safe compilation with default 10,000 depth limitCompilerError- Detailed error types and descriptionsrender()- Convert compiled documents to strings