nom_tracer/
macros.rs

1// Copyright (c) Hexbee
2// SPDX-License-Identifier: Apache-2.0
3
4#[doc(hidden)]
5#[macro_export]
6macro_rules! __fn_name {
7    () => {{
8        struct Here;
9        const PREFIX: &str = concat!(module_path!(), "::");
10        const SUFFIX: &str = "::Here";
11        let here = core::any::type_name::<Here>();
12        &here[PREFIX.len()..(here.len() - SUFFIX.len())]
13    }};
14}
15
16/// Adds tracing to a parser.
17///
18/// This macro wraps a parser with tracing functionality.
19/// It can be used with different combinations of tags, contexts, and parsers.
20///
21/// # Usage
22///
23/// - `trace!(parser)`: Uses the default tag and no context.
24/// - `trace!(tag, parser)`: Uses a custom tag and no context.
25/// - `trace!("context", parser)`: Uses the default tag and a custom context.
26/// - `trace!(tag, "context", parser)`: Uses a custom tag and a custom context.
27///
28/// When the trace feature is disabled, this macro becomes a no-op and simply returns the parser.
29#[cfg(any(feature = "trace", feature = "trace-context"))]
30#[macro_export]
31macro_rules! trace {
32    ($parser:expr $(,)?) => {
33        $crate::tr($crate::DEFAULT_TAG, None, $crate::__fn_name!(), $parser)
34    };
35
36    ($tag:ident, $parser:expr $(,)?) => {
37        $crate::tr(stringify!($tag), None, $crate::__fn_name!(), $parser)
38    };
39
40    ($context:expr, $parser:expr $(,)?) => {
41        $crate::tr(
42            $crate::DEFAULT_TAG,
43            Some($context),
44            $crate::__fn_name!(),
45            $parser,
46        )
47    };
48
49    ($tag:ident, $context:expr, $parser:expr $(,)?) => {
50        $crate::tr(
51            stringify!($tag),
52            Some($context),
53            $crate::__fn_name!(),
54            $parser,
55        )
56    };
57
58    ($caller:expr, $tag:ident, $parser:expr $(,)?) => {{
59        $crate::tr(stringify!($tag), None, $caller, $parser)
60    }};
61
62    ($caller:expr, $context:expr, $parser:expr $(,)?) => {{
63        $crate::tr($crate::DEFAULT_TAG, Some($context), $caller, $parser)
64    }};
65
66    ($caller:expr, $tag:ident, $context:expr, $parser:expr $(,)?) => {{
67        $crate::tr(stringify!($tag), Some($context), $caller, $parser)
68    }};
69}
70#[cfg(not(any(feature = "trace", feature = "trace-context")))]
71#[macro_export]
72macro_rules! trace {
73    ($parser:expr $(,)?) => {
74        $parser
75    };
76    ($tag:ident, $parser:expr $(,)?) => {
77        $parser
78    };
79    ($context:expr, $parser:expr $(,)?) => {
80        $parser
81    };
82    ($tag:ident, $context:expr, $parser:expr $(,)?) => {
83        $parser
84    };
85
86    ($caller:expr, $tag:ident, $parser:expr $(,)?) => {{
87        $parser
88    }};
89
90    ($caller:expr, $context:expr, $parser:expr $(,)?) => {{
91        $parser
92    }};
93
94    ($caller:expr, $tag:ident, $context:expr, $parser:expr $(,)?) => {{
95        $parser
96    }};
97}
98
99/// Silences the tracing for a subtree of parsers.
100///
101/// This macro wraps a parser and prevents it and its sub-parsers from generating trace output.
102/// It's useful for reducing noise in the trace output for well-tested or less interesting parts of your parser.
103///
104/// # Usage
105///
106/// - `silence_tree!(parser)`: Silences the default tag.
107/// - `silence_tree!(tag, parser)`: Silences a specific tag.
108/// - `silence_tree!("context", parser)`: Silences the default tag with a context.
109/// - `silence_tree!(tag, "context", parser)`: Silences a specific tag with a context.
110#[cfg(feature = "trace-silencing")]
111#[macro_export]
112macro_rules! silence_tree {
113    ($parser:expr $(,)?) => {{
114        let caller = $crate::__fn_name!();
115        $crate::silence_tree($crate::DEFAULT_TAG, None, caller, $parser)
116    }};
117
118    ($tag:ident, $parser:expr $(,)?) => {{
119        let caller = $crate::__fn_name!();
120        $crate::silence_tree(stringify!($tag), None, caller, $parser)
121    }};
122
123    ($context:expr, $parser:expr $(,)?) => {{
124        let caller = $crate::__fn_name!();
125        $crate::silence_tree($crate::DEFAULT_TAG, Some($context), caller, $parser)
126    }};
127
128    ($tag:ident, $context:expr, $parser:expr $(,)?) => {{
129        let caller = $crate::__fn_name!();
130        $crate::silence_tree(stringify!($tag), Some($context), caller, $parser)
131    }};
132
133    ($caller:expr, $tag:ident, $parser:expr $(,)?) => {{
134        $crate::silence_tree(stringify!($tag), None, $caller, $parser)
135    }};
136
137    ($caller:expr, $context:expr, $parser:expr $(,)?) => {{
138        $crate::silence_tree($crate::DEFAULT_TAG, Some($context), $caller, $parser)
139    }};
140
141    ($caller:expr, $tag:ident, $context:expr, $parser:expr $(,)?) => {{
142        $crate::silence_tree(stringify!($tag), Some($context), $caller, $parser)
143    }};
144}
145
146/// Activates tracing for a specific tag or the default tag.
147///
148/// # Usage
149///
150/// - `activate_trace!()`: Activates tracing for the default tag.
151/// - `activate_trace!(tag)`: Activates tracing for a specific tag.
152#[cfg(feature = "trace")]
153#[macro_export]
154macro_rules! activate_trace (
155    () => {
156        $crate::TRACE_TAGS.with(|trace| {
157            trace.borrow_mut().activate($crate::DEFAULT_TAG);
158        });
159    };
160    ($tag:ident) => {
161        $crate::TRACE_TAGS.with(|trace| {
162            trace.borrow_mut().activate(stringify!($tag));
163        });
164    };
165);
166#[cfg(not(feature = "trace"))]
167#[macro_export]
168macro_rules! activate_trace (
169    () => {};
170    ($tag:ident) => {};
171);
172
173/// Deactivates tracing for a specific tag or the default tag.
174///
175/// # Usage
176///
177/// - `deactivate_trace!()`: Deactivates tracing for the default tag.
178/// - `deactivate_trace!(tag)`: Deactivates tracing for a specific tag.
179#[cfg(feature = "trace")]
180#[macro_export]
181macro_rules! deactivate_trace (
182    () => {
183        $crate::TRACE_TAGS.with(|trace| {
184            trace.borrow_mut().deactivate($crate::DEFAULT_TAG);
185        });
186    };
187
188    ($tag:ident) => {
189        $crate::TRACE_TAGS.with(|trace| {
190            trace.borrow_mut().deactivate(stringify!($tag));
191        });
192    };
193);
194#[cfg(not(feature = "trace"))]
195#[macro_export]
196macro_rules! deactivate_trace (
197    () => {};
198    ($tag:ident) => {};
199);
200
201/// Activates real-time printing of trace events for a specific tag or the default tag.
202///
203/// # Usage
204///
205/// - `activate_trace_print!()`: Activates trace printing for the default tag.
206/// - `activate_trace_print!(tag)`: Activates trace printing for a specific tag.
207#[cfg(feature = "trace-print")]
208#[macro_export]
209macro_rules! activate_trace_print (
210    () => {
211        $crate::TRACE_TAGS.with(|trace| {
212            trace.borrow_mut().activate_trace_print($crate::DEFAULT_TAG);
213        });
214    };
215    ($tag:ident) => {
216        $crate::TRACE_TAGS.with(|trace| {
217            trace.borrow_mut().activate_trace_print(stringify!($tag));
218        });
219    };
220);
221#[cfg(not(feature = "trace-print"))]
222#[macro_export]
223macro_rules! activate_trace_print (
224    () => {};
225    ($tag:ident) => {};
226);
227
228/// Deactivates real-time printing of trace events for a specific tag or the default tag.
229///
230/// # Usage
231///
232/// - `deactivate_trace_print!()`: Deactivates trace printing for the default tag.
233/// - `deactivate_trace_print!(tag)`: Deactivates trace printing for a specific tag.
234#[cfg(feature = "trace")]
235#[macro_export]
236macro_rules! deactivate_trace_print (
237    () => {
238        $crate::TRACE_TAGS.with(|trace| {
239            trace.borrow_mut().deactivate_trace_print($crate::DEFAULT_TAG);
240        });
241    };
242
243    ($tag:ident) => {
244        $crate::TRACE_TAGS.with(|trace| {
245            trace.borrow_mut().deactivate_trace_print(stringify!($tag));
246        });
247    };
248);
249#[cfg(not(feature = "trace"))]
250#[macro_export]
251macro_rules! deactivate_trace_print (
252    () => {};
253    ($tag:ident) => {};
254);
255
256/// Resets the trace for a specific tag or the default tag.
257///
258/// This clears all recorded events for the specified tag.
259///
260/// # Usage
261///
262/// - `reset_trace!()`: Resets the trace for the default tag.
263/// - `reset_trace!(tag)`: Resets the trace for a specific tag.
264#[cfg(feature = "trace")]
265#[macro_export]
266macro_rules! reset_trace (
267    () => {
268        $crate::TRACE_TAGS.with(|trace| {
269            trace.borrow_mut().clear($crate::DEFAULT_TAG);
270        });
271    };
272
273    ($tag:ident) => {
274        $crate::TRACE_TAGS.with(|trace| {
275            trace.borrow_mut().clear(stringify!($tag));
276        });
277    };
278);
279#[cfg(not(feature = "trace"))]
280#[macro_export]
281macro_rules! reset_trace (
282    () => {};
283    ($tag:ident) => {};
284);
285
286/// Sets the maximum nesting level for tracing.
287///
288/// When the nesting level exceeds this value, the parser will panic. This is useful for
289/// detecting infinite recursion or excessively deep parser nesting.
290///
291/// # Usage
292///
293/// - `set_max_level!(level)`: Sets the max level for the default tag.
294/// - `set_max_level!(tag, level)`: Sets the max level for a specific tag.
295///
296/// The `level` parameter should be an `Option<usize>`. Use `None` to remove the limit.
297#[cfg(feature = "trace-max-level")]
298#[macro_export]
299macro_rules! set_max_level (
300    ($level:expr) => {
301        $crate::TRACE_TAGS.with(|trace| {
302            trace.borrow_mut().panic_on_level($crate::DEFAULT_TAG, $level);
303        });
304    };
305    ($tag:ident, $level:expr) => {
306        $crate::TRACE_TAGS.with(|trace| {
307            trace.borrow_mut().panic_on_level(stringify!($tag), $level);
308        });
309    };
310);
311#[cfg(not(feature = "trace-max-level"))]
312#[macro_export]
313macro_rules! set_max_level (
314    ($level:expr) => {};
315    ($tag:ident, $level:expr) => {};
316);
317
318/// Retrieves the trace for a specific tag or the default tag.
319///
320/// # Usage
321///
322/// - `get_trace!()`: Gets the trace for the default tag.
323/// - `get_trace!(tag)`: Gets the trace for a specific tag.
324///
325/// # Returns
326///
327/// Returns a `String` containing the trace output.
328#[macro_export]
329macro_rules! get_trace {
330    () => {
331        $crate::get_trace_for_tag($crate::DEFAULT_TAG)
332    };
333    ($tag:ident) => {
334        $crate::get_trace_for_tag(stringify!($tag))
335    };
336}
337
338/// Prints the trace for a specific tag or the default tag.
339///
340/// # Usage
341///
342/// - `print_trace!()`: Prints the trace for the default tag.
343/// - `print_trace!(tag)`: Prints the trace for a specific tag.
344#[macro_export]
345macro_rules! print_trace {
346    () => {
347        $crate::print_trace_for_tag($crate::DEFAULT_TAG);
348    };
349    ($tag:ident) => {
350        $crate::print_trace_for_tag(stringify!($tag));
351    };
352}