Skip to main content

pistonite_cu/cli/
macros.rs

1use cu::cli::printer::{PRINTER, PrintPayload};
2use cu::lv;
3/// Print something
4///
5/// This is similar to `info`, but unlike info, this message will still log with `-q`.
6#[macro_export]
7#[cfg(feature = "print")]
8macro_rules! print {
9    ($($fmt_args:tt)*) => {{
10        $crate::cli::__print_with_level($crate::lv::P, format_args!($($fmt_args)*));
11    }}
12}
13/// Logs a hint message
14#[macro_export]
15#[cfg(feature = "print")]
16macro_rules! hint {
17    ($($fmt_args:tt)*) => {{
18        $crate::cli::__print_with_level($crate::lv::H, format_args!($($fmt_args)*));
19    }}
20}
21
22/// Print message with a custom log format and level.
23///
24/// This lets you customize the "level char", the separator char, and
25/// the colors for level char, separator char, and the main text color.
26/// Note that if colors are disabled from CLI (--color=never), the control
27/// sequences are replaced with empty string.
28///
29/// ```rust
30/// # use pistonite_cu as cu;
31/// static GREEN: &str = "\x1b[92m";
32/// static RED: &str = "\x1b[91m";
33/// static YELLOW: &str = "\x1b[93m";
34/// static RESET: &str = "\x1b[0m";
35///
36/// /// This logs P) in green
37/// macro_rules! pass {
38///    ($($args:tt)*) => { cu::custom_print!(cu::lv::I, GREEN, 'P', "", ')', GREEN, $($args)*) }
39/// }
40///
41/// /// This logs F) in red
42/// macro_rules! fail {
43///    ($($args:tt)*) => { cu::custom_print!(cu::lv::E, RED, 'F', "", ')', RED, $($args)*) }
44/// }
45///
46/// let count = 5;
47/// pass!("{count} tests passed");
48/// fail!("{count} tests failed");
49/// // the part after reset remains red
50/// fail!("{YELLOW}some{RESET} tests failed");
51/// ```
52#[macro_export]
53#[cfg(feature = "print")]
54macro_rules! custom_print {
55    (
56        $level:expr, $level_char_control:expr, $level_char:expr,
57        $sep_char_control:expr, $sep_char:expr, $text_control:expr,
58        $($fmt_args:tt)*
59    ) => {{
60        $crate::cli::__print_payload_with_level(
61            $level,
62            $level_char_control,
63            $level_char,
64            $sep_char_control,
65            $sep_char,
66            $text_control,
67            format_args!($($fmt_args)*)
68        );
69    }};
70}
71
72/// Show prompt to the user. See [Prompting](fn@crate::prompt)
73#[cfg(all(feature = "prompt", not(feature = "coroutine")))]
74#[macro_export]
75macro_rules! prompt {
76    ($($fmt_args:tt)*) => {{
77        $crate::cli::prompt(format!($($fmt_args)*)).or_cancel().run()
78    }};
79}
80
81/// Show prompt to the user. See [Prompting](fn@crate::prompt)
82#[cfg(all(feature = "prompt", feature = "coroutine"))]
83#[macro_export]
84macro_rules! prompt {
85    (async $($fmt_args:tt)*) => {{
86        $crate::cli::prompt(format!($($fmt_args)*)).or_cancel().co_run().await
87        }};
88    ($($fmt_args:tt)*) => {{
89        $crate::cli::prompt(format!($($fmt_args)*)).or_cancel().run()
90    }};
91}
92
93/// Show a Yes/No prompt. See [Prompting](fn@crate::prompt)
94#[cfg(all(feature = "prompt", not(feature = "coroutine")))]
95#[macro_export]
96macro_rules! yesno {
97    ($($fmt_args:tt)*) => {{
98        $crate::cli::yesno(format!($($fmt_args)*)).run()
99    }};
100}
101
102/// Show a Yes/No prompt. See [Prompting](fn@crate::prompt)
103#[cfg(all(feature = "prompt", feature = "coroutine"))]
104#[macro_export]
105macro_rules! yesno {
106    (async $($fmt_args:tt)*) => {{
107        $crate::cli::yesno(format!($($fmt_args)*)).co_run().await
108        }};
109    ($($fmt_args:tt)*) => {{
110        $crate::cli::yesno(format!($($fmt_args)*)).run()
111    }};
112}
113
114/// Internal print function for macros
115#[doc(hidden)]
116pub fn __print_with_level(lv: lv::Lv, message: std::fmt::Arguments<'_>) {
117    if !lv.can_print(lv::PRINT_LEVEL.get()) {
118        return;
119    }
120    let message = format!("{message}");
121    if let Ok(mut printer) = PRINTER.lock() {
122        if let Some(printer) = printer.as_mut() {
123            printer.print_message(lv, &message);
124        }
125    }
126}
127
128/// Internal print function for custom print formats
129#[doc(hidden)]
130pub fn __print_payload_with_level(
131    lv: lv::Lv,
132    mut level_char_control: &'static str,
133    level_char: char,
134    mut sep_char_control: &'static str,
135    sep_char: char,
136    mut text_control: &'static str,
137    message: std::fmt::Arguments<'_>,
138) {
139    if !lv.can_print(lv::PRINT_LEVEL.get()) {
140        return;
141    }
142    if !lv::color_enabled() {
143        level_char_control = "";
144        sep_char_control = "";
145        text_control = "";
146    }
147    let message = format!("{message}");
148    let payload = PrintPayload {
149        level_char_control,
150        level_char,
151        sep_char_control,
152        sep_char,
153        text_control,
154        message: &message,
155    };
156    if let Ok(mut printer) = PRINTER.lock() {
157        if let Some(printer) = printer.as_mut() {
158            printer.print_payload(payload);
159        }
160    }
161}