Skip to main content

cli_forge/
output.rs

1//! The plain output path: [`out`] and [`err`].
2//!
3//! These are the hot path and the common case — one call, no ceremony. They do
4//! no tag parsing and no styling work: the value is formatted straight to the
5//! stream and followed by a newline. Passing a plain `&str` is a near-direct
6//! write with no heap allocation. Styling, when wanted, is paid for inside the
7//! value's own [`Display`] (a [`Style`](crate::Style) or the `String` from
8//! [`parse`](crate::parse) / [`tag`](crate::tag)), never here.
9
10use std::fmt::Display;
11use std::io::Write;
12
13/// Print `value` to standard output, followed by a newline.
14///
15/// The common case is a string literal, which is written without parsing or
16/// allocation. Because the argument is anything [`Display`], a
17/// [`Style`](crate::Style) drops straight in and renders on the way out.
18///
19/// A failed write — a closed pipe, for instance — is silently ignored: a
20/// fire-and-forget print must not panic or abort the program.
21///
22/// # Examples
23///
24/// ```
25/// use cli_forge::{out, style};
26///
27/// out("building...");                 // plain, allocation-free
28/// out(style("done").green().bold());  // styled, rendered on write
29/// out(format!("built {} targets", 3)); // any Display value
30/// ```
31pub fn out<T: Display>(value: T) {
32    let stdout = std::io::stdout();
33    let mut handle = stdout.lock();
34    // A broken pipe or closed stream is unrecoverable from a print helper and
35    // must not abort the program, so the write result is deliberately dropped.
36    let _ = writeln!(handle, "{value}");
37}
38
39/// Print `value` to standard error, followed by a newline.
40///
41/// The standard-error counterpart of [`out`], with the same contract: no
42/// parsing, no allocation for plain strings, and write errors silently ignored.
43///
44/// # Examples
45///
46/// ```
47/// use cli_forge::{err, style};
48///
49/// err("something went wrong");
50/// err(style("ERROR:").red().bold());
51/// ```
52pub fn err<T: Display>(value: T) {
53    let stderr = std::io::stderr();
54    let mut handle = stderr.lock();
55    // See `out`: a failed write to a print helper is intentionally ignored.
56    let _ = writeln!(handle, "{value}");
57}