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}