• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![allow(dead_code)]
2 
3 #[cfg(any(feature = "debug", feature = "profile"))]
4 use core::fmt::{Debug, Display, Write};
5 #[cfg(any(feature = "debug", feature = "profile"))]
6 use std::sync::Mutex;
7 
8 #[doc(hidden)]
9 #[cfg(any(feature = "debug", feature = "profile"))]
10 pub struct DebugLogger {
11     stack: Mutex<Vec<String>>,
12 }
13 
14 #[cfg(any(feature = "debug", feature = "profile"))]
15 static EMPTY_STRING: String = String::new();
16 #[cfg(any(feature = "debug", feature = "profile"))]
17 impl DebugLogger {
new() -> Self18     pub const fn new() -> Self {
19         Self { stack: Mutex::new(Vec::new()) }
20     }
21 
push_node(&self, new_key: crate::NodeId)22     pub fn push_node(&self, new_key: crate::NodeId) {
23         let mut stack = self.stack.lock().unwrap();
24         let mut key_string = String::new();
25         write!(&mut key_string, "{:?}", new_key).unwrap();
26         stack.push(key_string);
27     }
28 
pop_node(&self)29     pub fn pop_node(&self) {
30         let mut stack = self.stack.lock().unwrap();
31         stack.pop();
32     }
33 
log(&self, message: impl Display)34     pub fn log(&self, message: impl Display) {
35         let stack = self.stack.lock().unwrap();
36         let key = stack.last().unwrap_or(&EMPTY_STRING);
37         let level = stack.len() * 4;
38         let space = " ";
39         println!("{space:level$}{key}: {message}");
40     }
41 
labelled_log(&self, label: &str, message: impl Display)42     pub fn labelled_log(&self, label: &str, message: impl Display) {
43         let stack = self.stack.lock().unwrap();
44         let key = stack.last().unwrap_or(&EMPTY_STRING);
45         let level = stack.len() * 4;
46         let space = " ";
47         println!("{space:level$}{key}: {label} {message}");
48     }
49 
debug_log(&self, message: impl Debug)50     pub fn debug_log(&self, message: impl Debug) {
51         let stack = self.stack.lock().unwrap();
52         let key = stack.last().unwrap_or(&EMPTY_STRING);
53         let level = stack.len() * 4;
54         let space = " ";
55         println!("{space:level$}{key}: {message:?}");
56     }
57 
labelled_debug_log(&self, label: &str, message: impl Debug)58     pub fn labelled_debug_log(&self, label: &str, message: impl Debug) {
59         let stack = self.stack.lock().unwrap();
60         let key = stack.last().unwrap_or(&EMPTY_STRING);
61         let level = stack.len() * 4;
62         let space = " ";
63         println!("{space:level$}{key}: {label} {message:?}");
64     }
65 }
66 
67 #[cfg(any(feature = "debug", feature = "profile"))]
68 pub(crate) static NODE_LOGGER: DebugLogger = DebugLogger::new();
69 
70 macro_rules! debug_log {
71     // String literal label with debug printing
72     ($label:literal, dbg:$item:expr) => {{
73         #[cfg(feature = "debug")]
74         $crate::util::debug::NODE_LOGGER.labelled_debug_log($label, $item);
75     }};
76     // String literal label with display printing
77     ($label:literal, $item:expr) => {{
78         #[cfg(feature = "debug")]
79         $crate::util::debug::NODE_LOGGER.labelled_log($label, $item);
80     }};
81     // Debug printing
82     (dbg:$item:expr) => {{
83         #[cfg(feature = "debug")]
84         $crate::util::debug::NODE_LOGGER.debug_log($item);
85     }};
86     // Display printing
87     ($item:expr) => {{
88         #[cfg(feature = "debug")]
89         $crate::util::debug::NODE_LOGGER.log($item);
90     }};
91     // Blank newline
92     () => {{
93         #[cfg(feature = "debug")]
94         println!();
95     }};
96 }
97 
98 macro_rules! debug_log_node {
99     ($known_dimensions: expr, $parent_size: expr, $available_space: expr, $run_mode: expr, $sizing_mode: expr) => {
100         debug_log!(dbg:$run_mode);
101         debug_log!("sizing_mode", dbg:$sizing_mode);
102         debug_log!("known_dimensions", dbg:$known_dimensions);
103         debug_log!("parent_size", dbg:$parent_size);
104         debug_log!("available_space", dbg:$available_space);
105     };
106 }
107 
108 macro_rules! debug_push_node {
109     ($node_id:expr) => {
110         #[cfg(any(feature = "debug", feature = "profile"))]
111         $crate::util::debug::NODE_LOGGER.push_node($node_id);
112         debug_log!("");
113     };
114 }
115 
116 macro_rules! debug_pop_node {
117     () => {
118         #[cfg(any(feature = "debug", feature = "profile"))]
119         $crate::util::debug::NODE_LOGGER.pop_node();
120     };
121 }
122 
123 #[cfg(feature = "profile")]
124 #[allow(unused_macros)]
125 macro_rules! time {
126     ($label:expr, $($code:tt)*) => {
127         let start = ::std::time::Instant::now();
128         $($code)*
129         let duration = ::std::time::Instant::now().duration_since(start);
130         crate::util::debug::NODE_LOGGER.log(format_args!("Performed {} in {}ms", $label, duration.as_millis()));
131     };
132 }
133 
134 #[cfg(not(feature = "profile"))]
135 #[allow(unused_macros)]
136 macro_rules! time {
137     ($label:expr, $($code:tt)*) => {
138         $($code)*
139     };
140 }
141 
142 #[allow(unused_imports)]
143 pub(crate) use {debug_log, debug_log_node, debug_pop_node, debug_push_node, time};
144