Skip to main content

v_log/
macros.rs

1// Copyright 2026 Henrik Dick. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11/// Clear a surface of the vlogger, including the messages that have been sent to it.
12///
13/// # Examples
14///
15/// ```
16/// use v_log::clear;
17///
18/// clear!("main_surface");
19/// ```
20#[macro_export]
21macro_rules! clear {
22    // clear!(vlogger: my_vlogger, target: "my_target", "my_surface")
23    (vlogger: $vlogger:expr, $surface:expr) => {
24        $crate::__private_api::clear(
25            $crate::__vlog_vlogger!($vlogger),
26            $crate::__private_api::module_path!(),
27            $surface,
28        )
29    };
30
31    // clear!(vlogger: my_vlogger, "my_surface")
32    (vlogger: $vlogger:expr, target: $target:expr, $surface:expr) => {
33        $crate::__private_api::clear($crate::__vlog_vlogger!($vlogger), $target, $surface)
34    };
35
36    // clear!(target: "my_target", "my_surface")
37    (target: $target:expr, $surface:expr) => {
38        $crate::__private_api::clear(
39            $crate::__vlog_vlogger!(__vlog_global_vlogger),
40            $target,
41            $surface,
42        )
43    };
44
45    // clear!("my_surface")
46    ($surface:expr) => {
47        $crate::__private_api::clear(
48            $crate::__vlog_vlogger!(__vlog_global_vlogger),
49            $crate::__private_api::module_path!(),
50            $surface,
51        )
52    };
53}
54
55/// Logs a message to the vlogger.
56///
57/// # Examples
58///
59/// ```
60/// use v_log::message;
61///
62/// # struct Position { x: f32, y: f32 }
63/// let pos = Position { x: 3.234, y: -1.223 };
64///
65/// message!("main_surface", color: Healthy, "Correct position");
66/// message!("main_surface", "Position is: x: {}, y: {}", pos.x, pos.y);
67/// ```
68#[macro_export]
69macro_rules! message {
70    // message!(vlogger: my_vlogger, target: "my_target", "my_surface", color: Base, "a {} event", "log")
71    (vlogger: $vlogger:expr, target: $target:expr, $surface:expr, $($arg:tt)+) => ({
72        $crate::__message!(
73            $crate::__vlog_vlogger!($vlogger),
74            $surface,
75            &($target, $crate::__private_api::module_path!(), $crate::__private_api::loc()),
76            $($arg)+
77        )
78    });
79
80    // message!(vlogger: my_vlogger, "my_surface", color: Base, "a {} event", "log")
81    (vlogger: $vlogger:expr, $surface:expr, $($arg:tt)+) => ({
82        $crate::__message!(
83            $crate::__vlog_vlogger!($vlogger),
84            $surface,
85            &($crate::__private_api::module_path!(), $crate::__private_api::module_path!(), $crate::__private_api::loc()),
86            $($arg)+
87        )
88    });
89
90    // message!(target: "my_target", "my_surface", color: Base, "a {} event", "log")
91    (target: $target:expr, $surface:expr, $($arg:tt)+) => ({
92        $crate::__message!(
93            $crate::__vlog_vlogger!(__vlog_global_vlogger),
94            $surface,
95            &($target, $crate::__private_api::module_path!(), $crate::__private_api::loc()),
96            $($arg)+
97        )
98    });
99
100    // message!("my_surface", color: Base, "a {} event", "log")
101    ($surface:expr, $($arg:tt)+) => (
102        $crate::__message!(
103            $crate::__vlog_vlogger!(__vlog_global_vlogger),
104            $surface,
105            &($crate::__private_api::module_path!(), $crate::__private_api::module_path!(), $crate::__private_api::loc()),
106            $($arg)+
107        )
108    )
109}
110
111/// Sends a point to the vlogger.
112///
113/// # Examples
114///
115/// ```
116/// use v_log::point;
117///
118/// let pos1 = [3.234, -1.223];
119/// let pos2 = [2.713, 0.577];
120///
121/// point!("main_surface", pos1, 5.0, Base, "o", "Position is: x: {}, y: {}", pos1[0], pos1[1]);
122/// point!("main_surface", pos2, 5.0, Base);
123/// ```
124#[macro_export]
125macro_rules! point {
126    // point!(vlogger: my_vlogger, target: "my_target", "my_surface", [1.0, 2.0], 5.0, "o", "a {} event", "log")
127    (vlogger: $vlogger:expr, target: $target:expr, $surface:expr, $($arg:tt)+) => ({
128        $crate::__point!(
129            $crate::__vlog_vlogger!($vlogger),
130            $surface,
131            &($target, $crate::__private_api::module_path!(), $crate::__private_api::loc()),
132            $($arg)+
133        )
134    });
135
136    // point!(vlogger: my_vlogger, "my_surface", [1.0, 2.0], 5.0, "o", "a {} event", "log")
137    (vlogger: $vlogger:expr, $surface:expr, $($arg:tt)+) => ({
138        $crate::__point!(
139            $crate::__vlog_vlogger!($vlogger),
140            $surface,
141            &($crate::__private_api::module_path!(), $crate::__private_api::module_path!(), $crate::__private_api::loc()),
142            $($arg)+
143        )
144    });
145
146    // point!(target: "my_target", "my_surface", [1.0, 2.0], 5.0, "o", "a {} event", "log")
147    (target: $target:expr, $surface:expr, $($arg:tt)+) => ({
148        $crate::__point!(
149            $crate::__vlog_vlogger!(__vlog_global_vlogger),
150            $surface,
151            &($target, $crate::__private_api::module_path!(), $crate::__private_api::loc()),
152            $($arg)+
153        )
154    });
155
156    // point!("my_surface", [1.0, 2.0], 5.0, "o", "a {} event", "log")
157    ($surface:expr, $($arg:tt)+) => (
158        $crate::__point!(
159            $crate::__vlog_vlogger!(__vlog_global_vlogger),
160            $surface,
161            &($crate::__private_api::module_path!(), $crate::__private_api::module_path!(), $crate::__private_api::loc()),
162            $($arg)+
163        )
164    )
165}
166
167/// Sends a label/text annotation to the vlogger.
168///
169/// # Examples
170///
171/// ```
172/// use v_log::label;
173///
174/// let pos = [3.234, -1.223];
175///
176/// label!("main_surface", pos, (12.0, Base, "<"), "Position is: x: {}, y: {}", pos[0], pos[1]);
177/// label!("main_surface", pos, "Flexible position"); // with size 12.0, flexible alignment and "Base" color
178/// ```
179#[macro_export]
180macro_rules! label {
181    // label!(vlogger: my_vlogger, target: "my_target", "my_surface", [1.0, 2.0], 12.0, Base, "<", "a {} label", "log")
182    (vlogger: $vlogger:expr, target: $target:expr, $surface:expr, $($arg:tt)+) => ({
183        $crate::__label!(
184            $crate::__vlog_vlogger!($vlogger),
185            $surface,
186            &($target, $crate::__private_api::module_path!(), $crate::__private_api::loc()),
187            $($arg)+
188        )
189    });
190
191    // label!(vlogger: my_vlogger, "my_surface", [1.0, 2.0], 12.0, Base, "<", "a {} label", "log")
192    (vlogger: $vlogger:expr, $surface:expr, $($arg:tt)+) => ({
193        $crate::__label!(
194            $crate::__vlog_vlogger!($vlogger),
195            $surface,
196            &($crate::__private_api::module_path!(), $crate::__private_api::module_path!(), $crate::__private_api::loc()),
197            $($arg)+
198        )
199    });
200
201    // label!(target: "my_target", "my_surface", [1.0, 2.0], 12.0, Base, "<", "a {} label", "log")
202    (target: $target:expr, $surface:expr, $($arg:tt)+) => ({
203        $crate::__label!(
204            $crate::__vlog_vlogger!(__vlog_global_vlogger),
205            $surface,
206            &($target, $crate::__private_api::module_path!(), $crate::__private_api::loc()),
207            $($arg)+
208        )
209    });
210
211    // label!("my_surface", [1.0, 2.0], 12.0, Base, "<", "a {} label", "log")
212    ($surface:expr, $($arg:tt)+) => (
213        $crate::__label!(
214            $crate::__vlog_vlogger!(__vlog_global_vlogger),
215            $surface,
216            &($crate::__private_api::module_path!(), $crate::__private_api::module_path!(), $crate::__private_api::loc()),
217            $($arg)+
218        )
219    )
220}
221
222/// Sends an open or closed polyline to the vlogger.
223///
224/// # Examples
225///
226/// ```
227/// use v_log::polyline;
228///
229/// let pos1 = [3.234, -1.223];
230/// let pos2 = [2.713, 0.577];
231/// let pos3 = [6.283, 0.692];
232///
233/// // text is only allowed on single lines
234/// polyline!("main_surface", (pos1, pos2), 5.0, Base, "--", "Position is: x: {}, y: {}", pos1[0], pos1[1]);
235/// polyline!("main_surface", (pos1, pos2), 5.0, Base, "--");
236/// polyline!("main_surface", (pos1, pos2), 5.0, Base);
237/// polyline!("main_surface", (pos1, pos2, pos3), 5.0, Base, "--");
238/// polyline!("main_surface", (pos1, pos2, pos3), 5.0, Base);
239/// // adding a last , makes it closed -> draws a triangle
240/// polyline!("main_surface", (pos1, pos2, pos3,), 5.0, Base, "--");
241/// polyline!("main_surface", (pos1, pos2, pos3,), 5.0, Base);
242/// ```
243#[macro_export]
244macro_rules! polyline {
245    // polyline!(vlogger: my_vlogger, target: "my_target", "my_surface", [1.0, 2.0], 5.0, "o", Base, "a {} event", "log")
246    (vlogger: $vlogger:expr, target: $target:expr, $surface:expr, $($arg:tt)+) => ({
247        $crate::__line!(
248            $crate::__vlog_vlogger!($vlogger),
249            $surface,
250            &($target, $crate::__private_api::module_path!(), $crate::__private_api::loc()),
251            $($arg)+
252        )
253    });
254
255    // polyline!(vlogger: my_vlogger, "my_surface", [1.0, 2.0], 5.0, "o", Base, "a {} event", "log")
256    (vlogger: $vlogger:expr, $surface:expr, $($arg:tt)+) => ({
257        $crate::__line!(
258            $crate::__vlog_vlogger!($vlogger),
259            $surface,
260            &($crate::__private_api::module_path!(), $crate::__private_api::module_path!(), $crate::__private_api::loc()),
261            $($arg)+
262        )
263    });
264
265    // polyline!(target: "my_target", "my_surface", [1.0, 2.0], 5.0, "o", Base, "a {} event", "log")
266    (target: $target:expr, $surface:expr, $($arg:tt)+) => ({
267        $crate::__line!(
268            $crate::__vlog_vlogger!(__vlog_global_vlogger),
269            $surface,
270            &($target, $crate::__private_api::module_path!(), $crate::__private_api::loc()),
271            $($arg)+
272        )
273    });
274
275    // polyline!("my_surface", [1.0, 2.0], 5.0, "o", Base, "a {} event", "log")
276    ($surface:expr, $($arg:tt)+) => (
277        $crate::__line!(
278            $crate::__vlog_vlogger!(__vlog_global_vlogger),
279            $surface,
280            &($crate::__private_api::module_path!(), $crate::__private_api::module_path!(), $crate::__private_api::loc()),
281            $($arg)+
282        )
283    )
284}
285
286#[doc(hidden)]
287#[macro_export]
288#[clippy::format_args]
289macro_rules! __message {
290    ($vlogger:expr, $surface:expr, $loc:expr, color: $color:tt, $($arg:tt)+) => {
291        $crate::__private_api::vlog_message(
292            $vlogger,
293            $crate::__private_api::format_args!($($arg)+),
294            $crate::__color!($color),
295            $surface,
296            $loc
297        )
298    };
299    ($vlogger:expr, $surface:expr, $loc:expr, $($arg:tt)+) => {
300        $crate::__private_api::vlog_message(
301            $vlogger,
302            $crate::__private_api::format_args!($($arg)+),
303            $crate::__color!(Base),
304            $surface,
305            $loc
306        )
307    };
308}
309
310#[doc(hidden)]
311#[macro_export]
312#[clippy::format_args]
313macro_rules! __point {
314    ($vlogger:expr, $surface:expr, $loc:expr, $pos:expr, $size:expr, $color:tt, $style:tt, $($arg:tt)+) => {
315        $crate::__private_api::vlog_point(
316            $vlogger,
317            $crate::__private_api::format_args!($($arg)+),
318            $pos,
319            $size,
320            $crate::__color!($color),
321            $crate::__point_style!($style),
322            $surface,
323            $loc
324        )
325    };
326    ($vlogger:expr, $surface:expr, $loc:expr, $pos:expr, $size:expr, $color:tt, $style:tt) => {
327        $crate::__private_api::vlog_point(
328            $vlogger,
329            $crate::__private_api::format_args!(""),
330            $pos,
331            $size,
332            $crate::__color!($color),
333            $crate::__point_style!($style),
334            $surface,
335            $loc
336        )
337    };
338    ($vlogger:expr, $surface:expr, $loc:expr, $pos:expr, $size:expr, $color:tt) => {
339        $crate::__private_api::vlog_point(
340            $vlogger,
341            $crate::__private_api::format_args!(""),
342            $pos,
343            $size,
344            $crate::__color!($color),
345            $crate::__point_style!("o"),
346            $surface,
347            $loc
348        )
349    };
350}
351
352#[doc(hidden)]
353#[macro_export]
354#[clippy::format_args]
355macro_rules! __label {
356    ($vlogger:expr, $surface:expr, $loc:expr, $pos:expr, ($size:expr, $color:tt, $align:tt), $($arg:tt)+) => {
357        $crate::__private_api::vlog_label(
358            $vlogger,
359            $crate::__private_api::format_args!($($arg)+),
360            $pos,
361            $size,
362            $crate::__color!($color),
363            $crate::__alignment!($align),
364            $surface,
365            $loc
366        )
367    };
368    ($vlogger:expr, $surface:expr, $loc:expr, $pos:expr, $($arg:tt)+) => {
369        $crate::__private_api::vlog_label(
370            $vlogger,
371            $crate::__private_api::format_args!($($arg)+),
372            $pos,
373            12.0, // default size of 12 pixels
374            $crate::__color!(Base),
375            $crate::__alignment!("x"),
376            $surface,
377            $loc
378        )
379    };
380}
381
382#[doc(hidden)]
383#[macro_export]
384#[clippy::format_args]
385macro_rules! __line {
386    ($vlogger:expr, $surface:expr, $loc:expr, ($pos1:expr, $pos2:expr), $size:expr, $color:tt, $style:tt, $($arg:tt)+) => {
387        $crate::__private_api::vlog_line(
388            $vlogger,
389            $crate::__private_api::format_args!($($arg)+),
390            $pos1,
391            $pos2,
392            $size,
393            $crate::__color!($color),
394            $crate::__line_style!($style),
395            $surface,
396            $loc
397        )
398    };
399    ($vlogger:expr, $surface:expr, $loc:expr, ($pos1:expr, $pos2:expr), $size:expr, $color:tt) => {
400        $crate::__line!($vlogger, $surface, $loc, ($pos1, $pos2), $size, $color, "-")
401    };
402    ($vlogger:expr, $surface:expr, $loc:expr, ($pos1:expr, $($pos2:expr),+), $size:expr, $color:tt, $style:tt) => {
403        let mut last = $pos1;
404        $(
405        let next = $pos2;
406        $crate::__private_api::vlog_line(
407            $vlogger,
408            $crate::__private_api::format_args!(""),
409            last,
410            next.clone(),
411            $size,
412            $crate::__color!($color),
413            $crate::__line_style!($style),
414            $surface,
415            $loc
416        );
417        last = next;
418        )+
419    };
420    ($vlogger:expr, $surface:expr, $loc:expr, ($pos1:expr, $($pos2:expr),+), $size:expr, $color:tt) => {
421        $crate::__line!($vlogger, $surface, $loc, ($pos1, $($pos2),+), $size, $color, "-")
422    };
423    ($vlogger:expr, $surface:expr, $loc:expr, ($pos1:expr, $($pos2:expr,)+), $size:expr, $color:tt, $style:tt) => {
424        let mut last = $pos1;
425        let first = last.clone();
426        $(
427        let next = $pos2;
428        $crate::__private_api::vlog_line(
429            $vlogger,
430            $crate::__private_api::format_args!(""),
431            last,
432            next.clone(),
433            $size,
434            $crate::__color!($color),
435            $crate::__line_style!($style),
436            $surface,
437            $loc
438        );
439        last = next;
440        )+
441        $crate::__private_api::vlog_line(
442            $vlogger,
443            $crate::__private_api::format_args!(""),
444            last,
445            first,
446            $size,
447            $crate::__color!($color),
448            $crate::__line_style!($style),
449            $surface,
450            $loc
451        );
452    };
453    ($vlogger:expr, $surface:expr, $loc:expr, ($pos1:expr, $($pos2:expr,)+), $size:expr, $color:tt) => {
454        $crate::__line!($vlogger, $surface, $loc, ($pos1, $($pos2,)+), $size, $color, "-")
455    };
456}
457
458/// Determines if a message vlogged at the specified level in that module will
459/// be vlogged.
460///
461/// This can be used to avoid expensive computation of vlog message arguments if
462/// the message would be ignored anyway.
463///
464/// # Examples
465///
466/// ```
467/// use v_log::{message, vlog_enabled};
468///
469/// # struct Data { x: u32, y: u32 }
470/// # fn expensive_call() -> Data { Data { x: 0, y: 0 } }
471/// # let my_vlogger = v_log::__private_api::GlobalVLogger;
472/// if vlog_enabled!("main_surface") {
473///     let data = expensive_call();
474///     message!("main_surface", color: Info, "expensive debug data: {} {}", data.x, data.y);
475/// }
476///
477/// if vlog_enabled!(target: "Global", "main_surface") {
478///    let data = expensive_call();
479///    message!(target: "Global", "main_surface", "expensive debug data: {} {}", data.x, data.y);
480/// }
481///
482/// if vlog_enabled!(vlogger: my_vlogger, "main_surface") {
483///    let data = expensive_call();
484///    message!(target: "Global", "main_surface", "expensive debug data: {} {}", data.x, data.y);
485/// }
486/// ```
487#[macro_export]
488macro_rules! vlog_enabled {
489    // vlog_enabled!(vlogger: my_vlogger, target: "my_target", "my_surface")
490    (vlogger: $vlogger:expr, target: $target:expr, $surface:expr) => {{
491        $crate::__private_api::enabled($crate::__vlog_vlogger!($vlogger), $surface, $target)
492    }};
493
494    // vlog_enabled!(vlogger: my_vlogger, "my_surface")
495    (vlogger: $vlogger:expr, $surface:expr) => {{
496        $crate::__private_api::enabled(
497            $crate::__vlog_vlogger!($vlogger),
498            $surface,
499            $crate::__private_api::module_path!(),
500        )
501    }};
502
503    // vlog_enabled!(target: "my_target", "my_surface")
504    (target: $target:expr, $surface:expr) => {{
505        $crate::__private_api::enabled(
506            $crate::__vlog_vlogger!(__vlog_global_vlogger),
507            $surface,
508            $target,
509        )
510    }};
511
512    // vlog_enabled!("my_surface")
513    ($surface:expr) => {{
514        $crate::__private_api::enabled(
515            $crate::__vlog_vlogger!(__vlog_global_vlogger),
516            $surface,
517            $crate::__private_api::module_path!(),
518        )
519    }};
520}
521
522// Determine the vlogger to use, and whether to take it by-value or by reference
523
524#[doc(hidden)]
525#[macro_export]
526macro_rules! __vlog_vlogger {
527    (__vlog_global_vlogger) => {{
528        $crate::__private_api::GlobalVLogger
529    }};
530
531    ($vlogger:expr) => {{
532        &($vlogger)
533    }};
534}
535
536#[doc(hidden)]
537#[macro_export]
538macro_rules! __point_style {
539    ("O") => {
540        $crate::PointStyle::FilledCircle
541    };
542    ("-O") => {
543        $crate::PointStyle::Circle
544    };
545    ("--O") => {
546        $crate::PointStyle::DashedCircle
547    };
548    ("o") => {
549        $crate::PointStyle::Point
550    };
551    ("-o") => {
552        $crate::PointStyle::PointOutline
553    };
554    ("s") => {
555        $crate::PointStyle::PointSquare
556    };
557    ("-s") => {
558        $crate::PointStyle::PointSquareOutline
559    };
560    ("x") => {
561        $crate::PointStyle::PointCross
562    };
563    ("d") => {
564        $crate::PointStyle::PointDiamond
565    };
566    ("-d") => {
567        $crate::PointStyle::PointDiamondOutline
568    };
569    ($s:literal) => {
570        compile_error!(concat!("unknown point style ", $s))
571    };
572    ($s:ident) => {{
573        use $crate::PointStyle::*;
574        $s
575    }};
576}
577
578#[doc(hidden)]
579#[macro_export]
580macro_rules! __line_style {
581    ("-") => {
582        $crate::LineStyle::Simple
583    };
584    ("--") => {
585        $crate::LineStyle::Dashed
586    };
587    ("->") => {
588        $crate::LineStyle::Arrow
589    };
590    ("_>") => {
591        $crate::LineStyle::InsideHarpoonCCW
592    };
593    ("<_") => {
594        $crate::LineStyle::InsideHarpoonCW
595    };
596    ($s:literal) => {
597        panic!(concat!("unknown line style ", $s))
598    };
599    ($s:expr) => {{
600        use $crate::LineStyle::*;
601        $s
602    }};
603}
604
605#[doc(hidden)]
606#[macro_export]
607macro_rules! __alignment {
608    ("<") => {
609        $crate::TextAlignment::Left
610    };
611    (">") => {
612        $crate::TextAlignment::Right
613    };
614    (".") => {
615        $crate::TextAlignment::Center
616    };
617    ("x") => {
618        $crate::TextAlignment::Flexible
619    };
620    ($a:literal) => {
621        compile_error!(concat!("unknown text alignment ", $a))
622    };
623    ($a:expr) => {{
624        use $crate::TextAlignment::*;
625        $a
626    }};
627}
628
629#[doc(hidden)]
630#[macro_export]
631macro_rules! __color {
632    ($hex:literal) => {
633        $crate::Color::Hex($hex)
634    };
635    ($name:expr) => {{
636        use $crate::Color::*;
637        $name
638    }};
639}