build_print/lib.rs
1//! A simple set of macros that allow regular printing as well as properly formatted info,
2//! warnings, errors, and notes during build scripts.
3//!
4//! Traditionally, there are only two ways to print to the console during a build script:
5//! * `println!("cargo:warning=...")` to print a somewhat annoyingly formatted warning message
6//! * `panic!(..)` to halt the build process and print an error message
7//!
8//! Regular `println!` statements are not shown during the build process, so this crate hijacks
9//! the `cargo:warning=...` variant using ANSI escape sequences to produce a working
10//! [`println!`] macro as well as [`info!`], [`warn!`], [`error!`], and [`note!`] macros that
11//! following the indentation and coloring of standard cargo diagnostic messages.
12//!
13//! You can also define your own custom print messages using the [`custom_println!`] macro,
14//! which is also the basis for the other macros.
15//!
16//! # Example
17//! ```
18//! // build.rs
19//! use build_print::{println, *};
20//!
21//! fn main() {
22//! println!("regular println works");
23//! info!("hello world");
24//! warn!("hello world");
25//! error!("hello world");
26//! note!("hello world");
27//! custom_println!("Documenting", green, "hello world");
28//! }
29//! ```
30
31/// Analogue of [`std::println!`] that allows for printing to the console during a build
32/// script.
33#[macro_export]
34macro_rules! println {
35 () => {
36 ::std::println!("cargo:warning=\x1b[2K\r");
37 };
38 ($($arg:tt)*) => {
39 ::std::println!("cargo:warning=\x1b[2K\r{}", ::std::format!($($arg)*));
40 }
41}
42
43/// Allows for custom print messages with a specified prefix and color.
44///
45/// usage: `custom_println!("prefix", color, "message")` where color is one of `cyan`, `green`,
46/// `yellow`, or `red`. The `prefix` will be shown in bold in the specified color, followed by
47/// a colon and the message.
48#[macro_export]
49macro_rules! custom_println {
50 ($prefix:literal, cyan, $($arg:tt)*) => {
51 $crate::println!(" \x1b[1m\x1b[36m{}\x1b[0m {}", $prefix, ::std::format!($($arg)+));
52 };
53 ($prefix:literal, green, $($arg:tt)*) => {
54 $crate::println!(" \x1b[1m\x1b[32m{}\x1b[0m {}", $prefix, ::std::format!($($arg)+));
55 };
56 ($prefix:literal, yellow, $($arg:tt)*) => {
57 $crate::println!(" \x1b[1m\x1b[33m{}\x1b[0m {}", $prefix, ::std::format!($($arg)+));
58 };
59 ($prefix:literal, red, $($arg:tt)*) => {
60 $crate::println!(" \x1b[1m\x1b[31m{}\x1b[0m {}", $prefix, ::std::format!($($arg)+));
61 };
62}
63
64/// Can be used to print info messages during a build script.
65///
66/// Follows the same calling semantics as [`std::println!`]. Messages are prefixed with "info:"
67/// in green.
68#[macro_export]
69macro_rules! info {
70 ($($arg:tt)+) => {
71 $crate::custom_println!("info:", green, $($arg)+);
72 }
73}
74
75/// Can be used to print warning messages during a build script.
76///
77/// Follows the same calling semantics as [`std::println!`]. Messages are prefixed with
78/// "warning:" in yellow.
79#[macro_export]
80macro_rules! warn {
81 ($($arg:tt)+) => {
82 $crate::custom_println!("warning:", yellow, $($arg)+);
83 }
84}
85
86/// Can be used to print error messages during a build script without aborting the build.
87///
88/// Follows the same calling semantics as [`std::println!`]. Messages are prefixed with
89/// "error:" in red.
90#[macro_export]
91macro_rules! error {
92 ($($arg:tt)+) => {
93 $crate::custom_println!("error:", red, $($arg)+);
94 }
95}
96
97/// Can be used to print note messages during a build script.
98///
99/// Follows the same calling semantics as [`std::println!`]. Messages are prefixed with
100/// "note:" in cyan.
101#[macro_export]
102macro_rules! note {
103 ($($arg:tt)+) => {
104 $crate::custom_println!("note:", cyan, $($arg)+);
105 }
106}
107
108#[test]
109fn test_println_compiles() {
110 println!();
111 println!("hello world!");
112 println!("hello {}", 33);
113 println!("hello {}, {}, {}", 1, 2, 3);
114}
115
116#[test]
117fn test_info_compiles() {
118 info!("hello world!");
119 info!("hello {}", 33);
120 info!("hello {}, {}, {}", 1, 2, 3);
121}
122
123#[test]
124fn test_warn_compiles() {
125 warn!("hello world!");
126 warn!("hello {}", 33);
127 warn!("hello {}, {}, {}", 1, 2, 3);
128}
129
130#[test]
131fn test_error_compiles() {
132 error!("hello world!");
133 error!("hello {}", 33);
134 error!("hello {}, {}, {}", 1, 2, 3);
135}
136
137#[test]
138fn test_note_compiles() {
139 note!("hello world!");
140 note!("hello {}", 33);
141 note!("hello {}, {}, {}", 1, 2, 3);
142}