1mod external;
5mod reader;
6mod rename;
7mod sender;
8
9#[doc(hidden)]
10pub use array_object::{ArrayObject, Pack, TryConcat};
11
12#[doc(hidden)]
13pub use bulletin_board_common::*;
14
15#[doc(hidden)]
16pub use reader::read_bulletin;
17pub use rename::Rename;
18pub use sender::Buffer;
19
20#[doc(hidden)]
21pub use sender::SENDER;
22
23use std::collections::HashMap;
24use std::sync::{LazyLock, Mutex};
25
26#[doc(hidden)]
27pub static COUNTER: LazyLock<Mutex<HashMap<String, u64>>> =
28 LazyLock::new(|| Mutex::new(HashMap::new()));
29
30#[doc(hidden)]
31pub static DATA_ACC: LazyLock<Mutex<HashMap<(String, String, String), Vec<ArrayObject>>>> =
32 LazyLock::new(|| Mutex::new(HashMap::new()));
33
34#[macro_export]
48macro_rules! dbgbb {
49 ($($x:expr),*) => {{
50 let sender = dbgbb::SENDER.lock().unwrap();
51 use dbgbb::{Rename, Pack};
52 let mut objs = vec![];
53 $(
54 let title = match $x.get_name() {
55 Some(name) => name,
56 None => stringify!($x).to_string(),
57 };
58 let tag = format!("{}:{}:{}", file!(), line!(), column!());
59 let obj: dbgbb::ArrayObject = $x.clone().try_into().unwrap();
60 objs.push((title, tag, obj));
61 )*
62 sender.post(objs).unwrap();
63 }};
64 (every => $n:literal, $($x:expr),*) => {{
65 let mut map = dbgbb::COUNTER.lock().unwrap();
66 let count = map.entry(format!("{}:{}:{}", file!(), line!(), column!())).or_insert(0);
67 if *count % $n == 0 {
68 dbgbb!($($x),*);
69 }
70 *count += 1;
71 }};
72 (oneshot => $n:literal, $($x:expr),*) => {{
73 let mut map = dbgbb::COUNTER.lock().unwrap();
74 let count = map.entry(format!("{}:{}:{}", file!(), line!(), column!())).or_insert(0);
75 if *count == $n {
76 dbgbb!($($x),*);
77 }
78 *count += 1;
79 }};
80}
81
82#[macro_export]
97macro_rules! dbgbb_acc {
98 (label => $label:literal, $($x:expr),*) => {{
99 use dbgbb::Rename;
100 let mut map = dbgbb::DATA_ACC.lock().unwrap();
101 $(
102 let title = match $x.get_name() {
103 Some(name) => name,
104 None => stringify!($x).to_string(),
105 };
106 let tag = format!("{}:{}:{}", file!(), line!(), column!());
107 let entry = map.entry(($label.to_string(), title, tag)).or_insert(vec![]);
108 let obj: dbgbb::ArrayObject = $x.clone().try_into().unwrap();
109 entry.push(obj);
110 )*
111 }};
112 (label => $label:literal, every => $n:literal, $($x:expr),*) => {{
113 let mut map = dbgbb::COUNTER.lock().unwrap();
114 let count = map.entry(format!("{}:{}:{}", file!(), line!(), column!())).or_insert(0);
115 if *count % $n == 0 {
116 dbgbb_acc!(label => $label, $($x),*);
117 }
118 *count += 1;
119 }};
120 ($label:literal => post) => {{
121 use dbgbb::{Pack, TryConcat};
122 let mut objs = vec![];
123 let sender = dbgbb::SENDER.lock().unwrap();
124 let mut map = dbgbb::DATA_ACC.lock().unwrap();
125 let keys: Vec<_> = map.keys()
126 .filter(|key| key.0 == $label)
127 .map(|key|key.clone())
128 .collect();
129 for key in keys {
130 let obj = map.remove(&key).unwrap().try_concat().unwrap();
131 objs.push((key.1, key.2, obj));
132 }
133 sender.post(objs).unwrap();
134 }};
135}
136
137#[macro_export]
148macro_rules! dbgbb_read {
149 ($title:literal, $tag:literal, rev => $revision:literal) => {{
150 let obj = dbgbb::read_bulletin(
151 $title.to_string(),
152 Some($tag.to_string()),
153 Some($revision as u64),
154 );
155 obj.try_into().unwrap()
156 }};
157 ($title:literal, $tag:literal) => {{
158 let obj = dbgbb::read_bulletin($title.to_string(), Some($tag.to_string()), None);
159 obj.try_into().unwrap()
160 }};
161 ($title:literal, rev => $revision:literal) => {{
162 let obj = dbgbb::read_bulletin($title.to_string(), None, Some($revision as u64));
163 obj.try_into().unwrap()
164 }};
165 ($title:literal) => {{
166 let obj = dbgbb::read_bulletin($title.to_string(), None, None);
167 obj.try_into().unwrap()
168 }};
169}
170
171#[macro_export]
181macro_rules! dbgbb_flatten {
182 ($x:expr, depth => 1) => {{
183 let sender = dbgbb::SENDER.lock().unwrap();
184 use dbgbb::{Pack, Rename};
185 let title = match $x.get_name() {
186 Some(name) => name,
187 None => stringify!($x).to_string(),
188 };
189 let tag = format!("{}:{}:{}", file!(), line!(), column!());
190 let mut objs = vec![];
191 for inner in $x.clone().iter() {
192 let obj: dbgbb::ArrayObject = inner.clone().try_into().unwrap();
193 objs.push((title.clone(), tag.clone(), obj));
194 }
195 sender.post(objs).unwrap();
196 }};
197 ($x:expr, depth => 2) => {{
198 let sender = dbgbb::SENDER.lock().unwrap();
199 use dbgbb::{Pack, Rename};
200 let title = match $x.get_name() {
201 Some(name) => name,
202 None => stringify!($x).to_string(),
203 };
204 let tag = format!("{}:{}:{}", file!(), line!(), column!());
205 let mut objs = vec![];
206 for inner0 in $x.clone().iter() {
207 for inner1 in inner0.iter() {
208 let obj: dbgbb::ArrayObject = inner1.clone().try_into().unwrap();
209 objs.push((title.clone(), tag.clone(), obj));
210 }
211 }
212 sender.post(objs).unwrap();
213 }};
214 ($x:expr, depth => 3) => {{
215 let sender = dbgbb::SENDER.lock().unwrap();
216 use dbgbb::{Pack, Rename};
217 let title = match $x.get_name() {
218 Some(name) => name,
219 None => stringify!($x).to_string(),
220 };
221 let tag = format!("{}:{}:{}", file!(), line!(), column!());
222 let mut objs = vec![];
223 for inner0 in $x.clone().iter() {
224 for inner1 in inner0.iter() {
225 for inner2 in inner1.iter() {
226 let obj: dbgbb::ArrayObject = inner2.clone().try_into().unwrap();
227 objs.push((title.clone(), tag.clone(), obj));
228 }
229 }
230 }
231 sender.post(objs).unwrap();
232 }};
233 ($x:expr, depth => 4) => {{
234 let sender = dbgbb::SENDER.lock().unwrap();
235 use dbgbb::{Pack, Rename};
236 let title = match $x.get_name() {
237 Some(name) => name,
238 None => stringify!($x).to_string(),
239 };
240 let tag = format!("{}:{}:{}", file!(), line!(), column!());
241 let mut objs = vec![];
242 for inner0 in $x.clone().iter() {
243 for inner1 in inner0.iter() {
244 for inner2 in inner1.iter() {
245 for inner3 in inner2.iter() {
246 let obj: dbgbb::ArrayObject = inner3.clone().try_into().unwrap();
247 objs.push((title.clone(), tag.clone(), obj));
248 }
249 }
250 }
251 }
252 sender.post(objs).unwrap();
253 }};
254}
255
256#[macro_export]
265macro_rules! dbgbb_concat {
266 ($x:expr, depth => 1) => {{
267 let sender = dbgbb::SENDER.lock().unwrap();
268 use dbgbb::{Pack, Rename, TryConcat};
269 let title = match $x.get_name() {
270 Some(name) => name,
271 None => stringify!($x).to_string(),
272 };
273 let tag = format!("{}:{}:{}", file!(), line!(), column!());
274 let mut objs = vec![];
275 for inner in $x.clone().iter() {
276 let obj: dbgbb::ArrayObject = inner.clone().try_into().unwrap();
277 objs.push(obj);
278 }
279 let cat = objs.try_concat().unwrap();
280 sender.post(vec![(title, tag, cat)]).unwrap();
281 }};
282 ($x:expr, depth => 2) => {{
283 let sender = dbgbb::SENDER.lock().unwrap();
284 use dbgbb::{Pack, Rename, TryConcat};
285 let title = match $x.get_name() {
286 Some(name) => name,
287 None => stringify!($x).to_string(),
288 };
289 let tag = format!("{}:{}:{}", file!(), line!(), column!());
290 let mut objs0 = vec![];
291 for inner0 in $x.clone().iter() {
292 let mut objs1 = vec![];
293 for inner1 in inner0.iter() {
294 let obj: dbgbb::ArrayObject = inner1.clone().try_into().unwrap();
295 objs1.push(obj);
296 }
297 let cat = objs1.try_concat().unwrap();
298 objs0.push(cat);
299 }
300 let cat = objs0.try_concat().unwrap();
301 sender.post(vec![(title, tag, cat)]).unwrap();
302 }};
303 ($x:expr, depth => 3) => {{
304 let sender = dbgbb::SENDER.lock().unwrap();
305 use dbgbb::{Pack, Rename, TryConcat};
306 let title = match $x.get_name() {
307 Some(name) => name,
308 None => stringify!($x).to_string(),
309 };
310 let tag = format!("{}:{}:{}", file!(), line!(), column!());
311 let mut objs0 = vec![];
312 for inner0 in $x.clone().iter() {
313 let mut objs1 = vec![];
314 for inner1 in inner0.iter() {
315 let mut objs2 = vec![];
316 for inner2 in inner1.iter() {
317 let obj: dbgbb::ArrayObject = inner2.clone().try_into().unwrap();
318 objs2.push(obj);
319 }
320 let cat = objs2.try_concat().unwrap();
321 objs1.push(cat);
322 }
323 let cat = objs1.try_concat().unwrap();
324 objs0.push(cat);
325 }
326 let cat = objs0.try_concat().unwrap();
327 sender.post(vec![(title, tag, cat)]).unwrap();
328 }};
329 ($x:expr, depth => 4) => {{
330 let sender = dbgbb::SENDER.lock().unwrap();
331 use dbgbb::{Pack, Rename, TryConcat};
332 let title = match $x.get_name() {
333 Some(name) => name,
334 None => stringify!($x).to_string(),
335 };
336 let tag = format!("{}:{}:{}", file!(), line!(), column!());
337 let mut objs0 = vec![];
338 for inner0 in $x.clone().iter() {
339 let mut objs1 = vec![];
340 for inner1 in inner0.iter() {
341 let mut objs2 = vec![];
342 for inner2 in inner1.iter() {
343 let mut objs3 = vec![];
344 for inner3 in inner2.iter() {
345 let obj: dbgbb::ArrayObject = inner3.clone().try_into().unwrap();
346 objs3.push(obj);
347 }
348 let cat = objs3.try_concat().unwrap();
349 objs2.push(cat);
350 }
351 let cat = objs2.try_concat().unwrap();
352 objs1.push(cat);
353 }
354 let cat = objs1.try_concat().unwrap();
355 objs0.push(cat);
356 }
357 let cat = objs0.try_concat().unwrap();
358 sender.post(vec![(title, tag, cat)]).unwrap();
359 }};
360}
361
362#[macro_export]
372macro_rules! dbgbb_index {
373 ($x:expr, depth => 1) => {{
374 let sender = dbgbb::SENDER.lock().unwrap();
375 use dbgbb::{Pack, Rename};
376 let title = match $x.get_name() {
377 Some(name) => name,
378 None => stringify!($x).to_string(),
379 };
380 let tag = format!("{}:{}:{}", file!(), line!(), column!());
381 let mut objs = vec![];
382 for (i, inner) in $x.clone().iter().enumerate() {
383 let obj: dbgbb::ArrayObject = inner.clone().try_into().unwrap();
384 objs.push((title.clone(), format!("{tag}:[{i}]"), obj));
385 }
386 sender.post(objs).unwrap();
387 }};
388 ($x:expr, depth => 2) => {{
389 let sender = dbgbb::SENDER.lock().unwrap();
390 use dbgbb::{Pack, Rename};
391 let title = match $x.get_name() {
392 Some(name) => name,
393 None => stringify!($x).to_string(),
394 };
395 let tag = format!("{}:{}:{}", file!(), line!(), column!());
396 let mut objs = vec![];
397 for (i, inner0) in $x.clone().iter().enumerate() {
398 for (j, inner1) in inner0.iter().enumerate() {
399 let obj: dbgbb::ArrayObject = inner1.clone().try_into().unwrap();
400 objs.push((title.clone(), format!("{tag}:[{i},{j}]"), obj));
401 }
402 }
403 sender.post(objs).unwrap();
404 }};
405 ($x:expr, depth => 3) => {{
406 let sender = dbgbb::SENDER.lock().unwrap();
407 use dbgbb::{Pack, Rename};
408 let title = match $x.get_name() {
409 Some(name) => name,
410 None => stringify!($x).to_string(),
411 };
412 let tag = format!("{}:{}:{}", file!(), line!(), column!());
413 let mut objs = vec![];
414 for (i, inner0) in $x.clone().iter().enumerate() {
415 for (j, inner1) in inner0.iter().enumerate() {
416 for (k, inner2) in inner1.iter().enumerate() {
417 let obj: dbgbb::ArrayObject = inner2.clone().try_into().unwrap();
418 objs.push((title.clone(), format!("{tag}:[{i},{j},{k}]"), obj));
419 }
420 }
421 }
422 sender.post(objs).unwrap();
423 }};
424 ($x:expr, depth => 4) => {{
425 let sender = dbgbb::SENDER.lock().unwrap();
426 use dbgbb::{Pack, Rename};
427 let title = match $x.get_name() {
428 Some(name) => name,
429 None => stringify!($x).to_string(),
430 };
431 let tag = format!("{}:{}:{}", file!(), line!(), column!());
432 let mut objs = vec![];
433 for (i, inner0) in $x.clone().iter().enumerate() {
434 for (j, inner1) in inner0.iter().enumerate() {
435 for (k, inner2) in inner1.iter().enumerate() {
436 for (l, inner3) in inner2.iter().enumerate() {
437 let obj: dbgbb::ArrayObject = inner3.clone().try_into().unwrap();
438 objs.push((title.clone(), format!("{tag}:[{i},{j},{k},{l}]"), obj));
439 }
440 }
441 }
442 }
443 sender.post(objs).unwrap();
444 }};
445}