mystical_runic/
debug.rs

1//! Debugging capabilities for v0.4.0 Developer Experience
2//! 
3//! Provides step-through debugging, variable tracking, and execution insights
4
5/// Debug information collected during template rendering
6#[derive(Debug, Clone)]
7pub struct DebugInfo {
8    /// Variables accessed during rendering
9    pub variables_accessed: Vec<String>,
10    /// Templates processed (including includes)
11    pub templates_processed: Vec<String>,
12    /// Step-by-step execution trace
13    pub execution_steps: Vec<ExecutionStep>,
14    /// Performance metrics
15    pub performance_metrics: PerformanceMetrics,
16}
17
18/// Individual step in template execution
19#[derive(Debug, Clone)]
20pub struct ExecutionStep {
21    /// Type of step (variable, conditional, loop, include, etc.)
22    pub step_type: String,
23    /// Content being processed
24    pub content: String,
25    /// Line number in template
26    pub line: usize,
27    /// Column number in template
28    pub column: usize,
29    /// Execution time for this step
30    pub duration_nanos: u64,
31    /// Result of this step
32    pub result: Option<String>,
33}
34
35/// Performance metrics for debugging
36#[derive(Debug, Clone)]
37pub struct PerformanceMetrics {
38    /// Total rendering time in nanoseconds
39    pub total_time_nanos: u64,
40    /// Time spent on variable resolution
41    pub variable_resolution_nanos: u64,
42    /// Time spent on template parsing
43    pub parsing_nanos: u64,
44    /// Time spent on includes
45    pub include_nanos: u64,
46    /// Memory usage in bytes
47    pub memory_usage_bytes: usize,
48}
49
50/// Result of template rendering with debug information
51#[derive(Debug)]
52pub struct DebugRenderResult {
53    /// The rendered output
54    pub output: String,
55    /// Debug information collected
56    pub debug_info: DebugInfo,
57}
58
59impl Default for DebugInfo {
60    fn default() -> Self {
61        Self::new()
62    }
63}
64
65impl DebugInfo {
66    /// Create new empty debug info
67    pub fn new() -> Self {
68        Self {
69            variables_accessed: Vec::new(),
70            templates_processed: Vec::new(),
71            execution_steps: Vec::new(),
72            performance_metrics: PerformanceMetrics::new(),
73        }
74    }
75    
76    /// Add a variable access to the debug trace
77    pub fn add_variable_access(&mut self, variable: &str) {
78        if !self.variables_accessed.contains(&variable.to_string()) {
79            self.variables_accessed.push(variable.to_string());
80        }
81    }
82    
83    /// Add a template processing to the debug trace
84    pub fn add_template_processed(&mut self, template: &str) {
85        self.templates_processed.push(template.to_string());
86    }
87    
88    /// Add an execution step to the debug trace
89    pub fn add_execution_step(&mut self, step: ExecutionStep) {
90        self.execution_steps.push(step);
91    }
92}
93
94impl Default for PerformanceMetrics {
95    fn default() -> Self {
96        Self::new()
97    }
98}
99
100impl PerformanceMetrics {
101    /// Create new empty performance metrics
102    pub fn new() -> Self {
103        Self {
104            total_time_nanos: 0,
105            variable_resolution_nanos: 0,
106            parsing_nanos: 0,
107            include_nanos: 0,
108            memory_usage_bytes: 0,
109        }
110    }
111}
112
113impl ExecutionStep {
114    /// Create a new execution step
115    pub fn new(step_type: &str, content: &str, line: usize, column: usize) -> Self {
116        Self {
117            step_type: step_type.to_string(),
118            content: content.to_string(),
119            line,
120            column,
121            duration_nanos: 0,
122            result: None,
123        }
124    }
125    
126    /// Set the result of this execution step
127    pub fn with_result(mut self, result: String) -> Self {
128        self.result = Some(result);
129        self
130    }
131    
132    /// Set the execution duration
133    pub fn with_duration(mut self, duration_nanos: u64) -> Self {
134        self.duration_nanos = duration_nanos;
135        self
136    }
137}