gioser

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 501HTML 254C 19JavaScript 81412 Sutichaykuna

Use macros to reduce noise from debug logging code (#561)

67f286f3666b621ef5ee2e1a1fbfb40a1084349e · ruwaq Nico Burns · (3 wata ñawpaq) · tayta 6031fa21b · kay commitpi sach'ata qhaway

Semántico sayk'uy · 12

src/compute/block.rs

  • ukhunpi t'ikrakurqan fn compute pub

src/compute/flexbox.rs

src/compute/grid/mod.rs

  • ukhunpi t'ikrakurqan fn compute pub

src/compute/leaf.rs

  • ukhunpi t'ikrakurqan fn compute pub

src/compute/taffy_tree.rs

src/util/debug.rs

9 qillqakuna · +117 −123

diff --git a/Cargo.toml b/Cargo.toml
index 5d21cc5cd..8beafdddb 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -29,8 +29,8 @@ grid = ["alloc", "dep:grid"]
 alloc = []
 std = ["num-traits/std", "grid?/std"]
 serde = ["dep:serde"]
-debug = []
-profile = []
+debug = ["std"]
+profile = ["std"]
 taffy_tree = ["dep:slotmap"]
 
 [dev-dependencies]
diff --git a/src/compute/block.rs b/src/compute/block.rs
index 00066c489..dd27bac88 100644
--- a/src/compute/block.rs
+++ b/src/compute/block.rs
@@ -5,14 +5,12 @@ use crate::style::{AvailableSpace, Display, LengthPercentageAuto, Overflow, Posi
 use crate::style_helpers::TaffyMaxContent;
 use crate::tree::{CollapsibleMarginSet, Layout, RunMode, SizeBaselinesAndMargins, SizingMode};
 use crate::tree::{LayoutTree, NodeId};
+use crate::util::debug::debug_log;
 use crate::util::sys::f32_max;
 use crate::util::sys::Vec;
 use crate::util::MaybeMath;
 use crate::util::{MaybeResolve, ResolveOrZero};
 
-#[cfg(feature = "debug")]
-use crate::util::debug::NODE_LOGGER;
-
 /// The public interface to Taffy's Block algorithm implementation
 pub struct BlockAlgorithm;
 impl LayoutAlgorithm for BlockAlgorithm {
@@ -141,8 +139,7 @@ pub fn compute(
         }
     }
 
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.log("BLOCK");
+    debug_log!("BLOCK");
     compute_inner(
         tree,
         node_id,
diff --git a/src/compute/flexbox.rs b/src/compute/flexbox.rs
index afb503c86..39ca93790 100644
--- a/src/compute/flexbox.rs
+++ b/src/compute/flexbox.rs
@@ -12,14 +12,12 @@ use crate::style::{
 use crate::style::{FlexDirection, Style};
 use crate::tree::{Layout, RunMode, SizeBaselinesAndMargins, SizingMode};
 use crate::tree::{LayoutTree, NodeId};
+use crate::util::debug::debug_log;
 use crate::util::sys::Vec;
 use crate::util::sys::{f32_max, new_vec_with_capacity};
 use crate::util::MaybeMath;
 use crate::util::{MaybeResolve, ResolveOrZero};
 
-#[cfg(feature = "debug")]
-use crate::util::debug::NODE_LOGGER;
-
 /// The public interface to Taffy's Flexbox algorithm implementation
 pub struct FlexboxAlgorithm;
 impl LayoutAlgorithm for FlexboxAlgorithm {
@@ -215,8 +213,7 @@ pub fn compute(
         }
     }
 
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.log("FLEX: single-pass");
+    debug_log!("FLEX: single-pass");
     compute_preliminary(tree, node, styled_based_known_dimensions, parent_size, available_space, run_mode)
 }
 
@@ -237,29 +234,26 @@ fn compute_preliminary(
     // 9.1. Initial Setup
 
     // 1. Generate anonymous flex items as described in §4 Flex Items.
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.log("generate_anonymous_flex_items");
+    debug_log!("generate_anonymous_flex_items");
     let mut flex_items = generate_anonymous_flex_items(tree, node, &constants);
 
     // 9.2. Line Length Determination
 
     // 2. Determine the available main and cross space for the flex items
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.log("determine_available_space");
+    debug_log!("determine_available_space");
     let available_space = determine_available_space(known_dimensions, available_space, &constants);
 
     // 3. Determine the flex base size and hypothetical main size of each item.
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.log("determine_flex_base_size");
+    debug_log!("determine_flex_base_size");
     determine_flex_base_size(tree, &constants, available_space, &mut flex_items);
 
     #[cfg(feature = "debug")]
     for item in flex_items.iter() {
-        NODE_LOGGER.labelled_log("item.flex_basis", item.flex_basis);
-        NODE_LOGGER.labelled_log("item.inner_flex_basis", item.inner_flex_basis);
-        NODE_LOGGER.labelled_debug_log("item.hypothetical_outer_size", item.hypothetical_outer_size);
-        NODE_LOGGER.labelled_debug_log("item.hypothetical_inner_size", item.hypothetical_inner_size);
-        NODE_LOGGER.labelled_debug_log("item.resolved_minimum_main_size", item.resolved_minimum_main_size);
+        debug_log!("item.flex_basis", item.flex_basis);
+        debug_log!("item.inner_flex_basis", item.inner_flex_basis);
+        debug_log!("item.hypothetical_outer_size", dbg:item.hypothetical_outer_size);
+        debug_log!("item.hypothetical_inner_size", dbg:item.hypothetical_inner_size);
+        debug_log!("item.resolved_minimum_main_size", dbg:item.resolved_minimum_main_size);
     }
 
     // 4. Determine the main size of the flex container
@@ -268,14 +262,12 @@ fn compute_preliminary(
     // 9.3. Main Size Determination
 
     // 5. Collect flex items into flex lines.
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.log("collect_flex_lines");
+    debug_log!("collect_flex_lines");
     let mut flex_lines = collect_flex_lines(&constants, available_space, &mut flex_items);
 
     // If container size is undefined, determine the container's main size
     // and then re-resolve gaps based on newly determined size
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.log("determine_container_main_size");
+    debug_log!("determine_container_main_size");
     let original_gap = constants.gap;
     if let Some(inner_main_size) = constants.node_inner_size.main(constants.dir) {
         let outer_main_size = inner_main_size + constants.content_box_inset.main_axis_sum(constants.dir);
@@ -287,10 +279,8 @@ fn compute_preliminary(
         constants.node_inner_size.set_main(constants.dir, Some(constants.inner_container_size.main(constants.dir)));
         constants.node_outer_size.set_main(constants.dir, Some(constants.container_size.main(constants.dir)));
 
-        #[cfg(feature = "debug")]
-        NODE_LOGGER.labelled_debug_log("constants.node_outer_size", constants.node_outer_size);
-        #[cfg(feature = "debug")]
-        NODE_LOGGER.labelled_debug_log("constants.node_inner_size", constants.node_inner_size);
+        debug_log!("constants.node_outer_size", dbg:constants.node_outer_size);
+        debug_log!("constants.node_inner_size", dbg:constants.node_inner_size);
 
         // Re-resolve percentage gaps
         let style = tree.style(node);
@@ -300,8 +290,7 @@ fn compute_preliminary(
     }
 
     // 6. Resolve the flexible lengths of all the flex items to find their used main size.
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.log("resolve_flexible_lengths");
+    debug_log!("resolve_flexible_lengths");
     for line in &mut flex_lines {
         resolve_flexible_lengths(line, &constants, original_gap);
     }
@@ -309,26 +298,22 @@ fn compute_preliminary(
     // 9.4. Cross Size Determination
 
     // 7. Determine the hypothetical cross size of each item.
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.log("determine_hypothetical_cross_size");
+    debug_log!("determine_hypothetical_cross_size");
     for line in &mut flex_lines {
         determine_hypothetical_cross_size(tree, line, &constants, available_space);
     }
 
     // Calculate child baselines. This function is internally smart and only computes child baselines
     // if they are necessary.
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.log("calculate_children_base_lines");
+    debug_log!("calculate_children_base_lines");
     calculate_children_base_lines(tree, known_dimensions, available_space, &mut flex_lines, &constants);
 
     // 8. Calculate the cross size of each flex line.
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.log("calculate_cross_size");
+    debug_log!("calculate_cross_size");
     calculate_cross_size(&mut flex_lines, known_dimensions, &constants);
 
     // 9. Handle 'align-content: stretch'.
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.log("handle_align_content_stretch");
+    debug_log!("handle_align_content_stretch");
     handle_align_content_stretch(&mut flex_lines, known_dimensions, &constants);
 
     // 10. Collapse visibility:collapse items. If any flex items have visibility: collapse,
@@ -347,27 +332,23 @@ fn compute_preliminary(
     // TODO implement once (if ever) we support visibility:collapse
 
     // 11. Determine the used cross size of each flex item.
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.log("determine_used_cross_size");
+    debug_log!("determine_used_cross_size");
     determine_used_cross_size(tree, &mut flex_lines, &constants);
 
     // 9.5. Main-Axis Alignment
 
     // 12. Distribute any remaining free space.
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.log("distribute_remaining_free_space");
+    debug_log!("distribute_remaining_free_space");
     distribute_remaining_free_space(&mut flex_lines, &constants);
 
     // 9.6. Cross-Axis Alignment
 
     // 13. Resolve cross-axis auto margins (also includes 14).
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.log("resolve_cross_axis_auto_margins");
+    debug_log!("resolve_cross_axis_auto_margins");
     resolve_cross_axis_auto_margins(&mut flex_lines, &constants);
 
     // 15. Determine the flex container’s used cross size.
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.log("determine_container_cross_size");
+    debug_log!("determine_container_cross_size");
     let total_line_cross_size = determine_container_cross_size(&flex_lines, known_dimensions, &mut constants);
 
     // We have the container size.
@@ -377,22 +358,18 @@ fn compute_preliminary(
     }
 
     // 16. Align all flex lines per align-content.
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.log("align_flex_lines_per_align_content");
+    debug_log!("align_flex_lines_per_align_content");
     align_flex_lines_per_align_content(&mut flex_lines, &constants, total_line_cross_size);
 
     // Do a final layout pass and gather the resulting layouts
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.log("final_layout_pass");
+    debug_log!("final_layout_pass");
     final_layout_pass(tree, &mut flex_lines, &constants);
 
     // Before returning we perform absolute layout on all absolutely positioned children
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.log("perform_absolute_layout_on_absolute_children");
+    debug_log!("perform_absolute_layout_on_absolute_children");
     perform_absolute_layout_on_absolute_children(tree, node, &constants);
 
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.log("hidden_layout");
+    debug_log!("hidden_layout");
     let len = tree.child_count(node);
     for order in 0..len {
         let child = tree.child(node, order);
diff --git a/src/compute/grid/mod.rs b/src/compute/grid/mod.rs
index 2cbbc42f2..3869201ab 100644
--- a/src/compute/grid/mod.rs
+++ b/src/compute/grid/mod.rs
@@ -6,6 +6,7 @@ use crate::style::{AlignContent, AlignItems, AlignSelf, AvailableSpace, Display,
 use crate::style_helpers::*;
 use crate::tree::{Layout, RunMode, SizeBaselinesAndMargins, SizingMode};
 use crate::tree::{LayoutTree, NodeId};
+use crate::util::debug::debug_log;
 use crate::util::sys::{f32_max, GridTrackVec, Vec};
 use crate::util::MaybeMath;
 use crate::util::{MaybeResolve, ResolveOrZero};
@@ -20,9 +21,6 @@ use types::{CellOccupancyMatrix, GridTrack};
 
 pub(crate) use types::{GridCoordinate, GridLine, OriginZeroLine};
 
-#[cfg(feature = "debug")]
-use crate::util::debug::NODE_LOGGER;
-
 use super::LayoutAlgorithm;
 
 mod alignment;
@@ -182,12 +180,9 @@ pub fn compute(
         height: outer_node_size.height.map(|space| space - content_box_inset.vertical_axis_sum()),
     };
 
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.labelled_debug_log("parent_size", parent_size);
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.labelled_debug_log("outer_node_size", outer_node_size);
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.labelled_debug_log("inner_node_size", inner_node_size);
+    debug_log!("parent_size", dbg:parent_size);
+    debug_log!("outer_node_size", dbg:outer_node_size);
+    debug_log!("inner_node_size", dbg:inner_node_size);
 
     // 5. Track Sizing
 
@@ -241,10 +236,8 @@ pub fn compute(
     let initial_row_sum = rows.iter().map(|track| track.base_size).sum::<f32>();
     inner_node_size.height = inner_node_size.height.or_else(|| initial_row_sum.into());
 
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.labelled_debug_log("initial_column_sum", initial_column_sum);
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.labelled_debug_log("initial_row_sum", initial_row_sum);
+    debug_log!("initial_column_sum", dbg:initial_column_sum);
+    debug_log!("initial_row_sum", dbg:initial_row_sum);
 
     // 6. Compute container size
     let resolved_style_size = known_dimensions.or(style.size.maybe_resolve(parent_size));
diff --git a/src/compute/leaf.rs b/src/compute/leaf.rs
index dfc37b1e5..6117c4ba4 100644
--- a/src/compute/leaf.rs
+++ b/src/compute/leaf.rs
@@ -5,13 +5,11 @@ use crate::style::{AvailableSpace, Display, Overflow, Position, Style};
 use crate::tree::CollapsibleMarginSet;
 use crate::tree::NodeId;
 use crate::tree::{SizeBaselinesAndMargins, SizingMode};
+use crate::util::debug::debug_log;
 use crate::util::sys::f32_max;
 use crate::util::MaybeMath;
 use crate::util::{MaybeResolve, ResolveOrZero};
 
-#[cfg(feature = "debug")]
-use crate::util::debug::NODE_LOGGER;
-
 /// Perform full layout on a leaf node
 #[allow(clippy::too_many_arguments)]
 pub(crate) fn perform_layout<NodeContext, MeasureFunction>(
@@ -116,14 +114,10 @@ where
         || border.top > 0.0
         || border.bottom > 0.0;
 
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.log("LEAF");
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.labelled_debug_log("node_size", node_size);
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.labelled_debug_log("min_size ", node_min_size);
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.labelled_debug_log("max_size ", node_max_size);
+    debug_log!("LEAF");
+    debug_log!("node_size", dbg:node_size);
+    debug_log!("min_size ", dbg:node_min_size);
+    debug_log!("max_size ", dbg:node_max_size);
 
     // Return early if both width and height are known
     if let Size { width: Some(width), height: Some(height) } = node_size {
diff --git a/src/compute/taffy_tree.rs b/src/compute/taffy_tree.rs
index d5cce7843..6339b3914 100644
--- a/src/compute/taffy_tree.rs
+++ b/src/compute/taffy_tree.rs
@@ -6,6 +6,7 @@ use crate::style::{AvailableSpace, Display};
 use crate::tree::{
     Layout, LayoutTree, NodeId, RunMode, SizeBaselinesAndMargins, SizingMode, Taffy, TaffyError, TaffyView,
 };
+use crate::util::debug::{debug_log, debug_log_node, debug_pop_node, debug_push_node};
 use crate::util::sys::round;
 
 #[cfg(feature = "block_layout")]
@@ -17,24 +18,6 @@ use crate::compute::FlexboxAlgorithm;
 #[cfg(feature = "grid")]
 use crate::compute::CssGridAlgorithm;
 
-#[cfg(any(feature = "debug", feature = "profile"))]
-use crate::util::debug::NODE_LOGGER;
-
-#[cfg(feature = "debug")]
-fn debug_log_node(
-    known_dimensions: Size<Option<f32>>,
-    parent_size: Size<Option<f32>>,
-    available_space: Size<AvailableSpace>,
-    run_mode: RunMode,
-    sizing_mode: SizingMode,
-) {
-    NODE_LOGGER.debug_log(run_mode);
-    NODE_LOGGER.labelled_debug_log("sizing_mode", sizing_mode);
-    NODE_LOGGER.labelled_debug_log("known_dimensions", known_dimensions);
-    NODE_LOGGER.labelled_debug_log("parent_size", parent_size);
-    NODE_LOGGER.labelled_debug_log("available_space", available_space);
-}
-
 /// Updates the stored layout of the provided `node` and its children
 pub(crate) fn compute_layout<NodeContext, MeasureFunction>(
     taffy_view: &mut TaffyView<NodeContext, MeasureFunction>,
@@ -132,31 +115,22 @@ fn compute_node_layout<NodeContext, MeasureFunction>(
 where
     MeasureFunction: FnMut(Size<Option<f32>>, Size<AvailableSpace>, NodeId, Option<&mut NodeContext>) -> Size<f32>,
 {
-    #[cfg(any(feature = "debug", feature = "profile"))]
-    NODE_LOGGER.push_node(node);
-    #[cfg(feature = "debug")]
-    println!();
+    debug_push_node!(node);
 
     let node_key = node.into();
     let has_children = !taffy_view.taffy.children[node_key].is_empty();
 
     // First we check if we have a cached result for the given input
     let cache_run_mode = if !has_children { RunMode::PerformLayout } else { run_mode };
-    if let Some(cached_size_and_baselines) =
-        taffy_view.taffy.nodes[node_key].cache.get(known_dimensions, available_space, cache_run_mode)
-    {
-        #[cfg(feature = "debug")]
-        NODE_LOGGER.labelled_debug_log("CACHE", cached_size_and_baselines.size);
-        #[cfg(feature = "debug")]
-        debug_log_node(known_dimensions, parent_size, available_space, run_mode, sizing_mode);
-        #[cfg(any(feature = "debug", feature = "profile"))]
-        NODE_LOGGER.pop_node();
-
+    let cache_entry = taffy_view.taffy.nodes[node_key].cache.get(known_dimensions, available_space, cache_run_mode);
+    if let Some(cached_size_and_baselines) = cache_entry {
+        debug_log!("CACHE", dbg:cached_size_and_baselines.size);
+        debug_log_node!(known_dimensions, parent_size, available_space, run_mode, sizing_mode);
+        debug_pop_node!();
         return cached_size_and_baselines;
     }
 
-    #[cfg(feature = "debug")]
-    debug_log_node(known_dimensions, parent_size, available_space, run_mode, sizing_mode);
+    debug_log_node!(known_dimensions, parent_size, available_space, run_mode, sizing_mode);
 
     /// Inlined function generic over the LayoutAlgorithm to reduce code duplication
     #[inline(always)]
@@ -170,8 +144,7 @@ where
         sizing_mode: SizingMode,
         vertical_margins_are_collapsible: Line<bool>,
     ) -> SizeBaselinesAndMargins {
-        #[cfg(feature = "debug")]
-        NODE_LOGGER.log(Algorithm::NAME);
+        debug_log!(Algorithm::NAME);
 
         match run_mode {
             RunMode::PerformLayout => Algorithm::perform_layout(
@@ -272,10 +245,8 @@ where
         computed_size_and_baselines,
     );
 
-    #[cfg(feature = "debug")]
-    NODE_LOGGER.labelled_debug_log("RESULT", computed_size_and_baselines.size);
-    #[cfg(any(feature = "debug", feature = "profile"))]
-    NODE_LOGGER.pop_node();
+    debug_log!("RESULT", dbg:computed_size_and_baselines.size);
+    debug_pop_node!();
 
     computed_size_and_baselines
 }
diff --git a/src/lib.rs b/src/lib.rs
index a531bf8aa..6c94f468d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -24,6 +24,7 @@ pub mod prelude;
 pub mod style;
 pub mod style_helpers;
 pub mod tree;
+#[macro_use]
 pub mod util;
 
 #[cfg(feature = "flexbox")]
diff --git a/src/util/debug.rs b/src/util/debug.rs
index 5c257533a..0a17069fa 100644
--- a/src/util/debug.rs
+++ b/src/util/debug.rs
@@ -2,15 +2,20 @@
 
 use crate::tree::NodeId;
 use crate::{style, LayoutTree};
+
+#[cfg(any(feature = "debug", feature = "profile"))]
 use core::fmt::{Debug, Display, Write};
+#[cfg(any(feature = "debug", feature = "profile"))]
 use std::sync::Mutex;
 
 /// Prints a debug representation of the computed layout for a tree of nodes, starting with the passed root node.
+#[cfg(feature = "std")]
 pub fn print_tree(tree: &impl LayoutTree, root: NodeId) {
     println!("TREE");
     print_node(tree, root, false, String::new());
 }
 
+#[cfg(feature = "std")]
 fn print_node(tree: &impl LayoutTree, node: NodeId, has_sibling: bool, lines_string: String) {
     let layout = &tree.layout(node);
     let style = &tree.style(node);
@@ -50,11 +55,14 @@ fn print_node(tree: &impl LayoutTree, node: NodeId, has_sibling: bool, lines_str
 }
 
 #[doc(hidden)]
+#[cfg(any(feature = "debug", feature = "profile"))]
 pub struct DebugLogger {
     stack: Mutex<Vec<String>>,
 }
 
+#[cfg(any(feature = "debug", feature = "profile"))]
 static EMPTY_STRING: String = String::new();
+#[cfg(any(feature = "debug", feature = "profile"))]
 impl DebugLogger {
     pub const fn new() -> Self {
         Self { stack: Mutex::new(Vec::new()) }
@@ -108,6 +116,59 @@ impl DebugLogger {
 #[cfg(any(feature = "debug", feature = "profile"))]
 pub(crate) static NODE_LOGGER: DebugLogger = DebugLogger::new();
 
+macro_rules! debug_log {
+    // String literal label with debug printing
+    ($label:literal, dbg:$item:expr) => {
+        #[cfg(feature = "debug")]
+        $crate::util::debug::NODE_LOGGER.labelled_debug_log($label, $item);
+    };
+    // String literal label with display printing
+    ($label:literal, $item:expr) => {
+        #[cfg(feature = "debug")]
+        $crate::util::debug::NODE_LOGGER.labelled_log($label, $item);
+    };
+    // Debug printing
+    (dbg:$item:expr) => {
+        #[cfg(feature = "debug")]
+        $crate::util::debug::NODE_LOGGER.debug_log($item);
+    };
+    // Display printing
+    ($item:expr) => {
+        #[cfg(feature = "debug")]
+        $crate::util::debug::NODE_LOGGER.log($item);
+    };
+    // Blank newline
+    () => {
+        #[cfg(feature = "debug")]
+        println!();
+    };
+}
+
+macro_rules! debug_log_node {
+    ($known_dimensions: expr, $parent_size: expr, $available_space: expr, $run_mode: expr, $sizing_mode: expr) => {
+        debug_log!(dbg:$run_mode);
+        debug_log!("sizing_mode", dbg:$sizing_mode);
+        debug_log!("known_dimensions", dbg:$known_dimensions);
+        debug_log!("parent_size", dbg:$parent_size);
+        debug_log!("available_space", dbg:$available_space);
+    };
+}
+
+macro_rules! debug_push_node {
+    ($node_id:expr) => {
+        #[cfg(any(feature = "debug", feature = "profile"))]
+        $crate::util::debug::NODE_LOGGER.push_node($node_id);
+        debug_log!("");
+    };
+}
+
+macro_rules! debug_pop_node {
+    () => {
+        #[cfg(any(feature = "debug", feature = "profile"))]
+        $crate::util::debug::NODE_LOGGER.pop_node();
+    };
+}
+
 #[cfg(feature = "profile")]
 #[allow(unused_macros)]
 macro_rules! time {
@@ -128,4 +189,4 @@ macro_rules! time {
 }
 
 #[allow(unused_imports)]
-pub(crate) use time;
+pub(crate) use {debug_log, debug_log_node, debug_pop_node, debug_push_node, time};
diff --git a/src/util/mod.rs b/src/util/mod.rs
index 324484ce9..71625108a 100644
--- a/src/util/mod.rs
+++ b/src/util/mod.rs
@@ -6,8 +6,8 @@ mod resolve;
 pub(crate) use resolve::{MaybeResolve, ResolveOrZero};
 pub(crate) mod sys;
 
-#[cfg(feature = "std")]
 #[doc(hidden)]
+#[macro_use]
 pub(crate) mod debug;
 #[cfg(feature = "std")]
 pub use debug::print_tree;