Crate bunt

source ·
Expand description

This crate offers a couple of macros to easily print colored and formatted text to a terminal. It is basically just a convenience API on top of termcolor. Thus, some understanding of termcolor is useful to use bunt.

Mini example:

let ty = "u32";
bunt::println!("{$bold+red}error:{/$} invalid value for type `{[blue]}`", ty);

Format string syntax

The macros in this crate have almost the same syntax as the corresponding std::fmt macros: arguments are inserted with {} and braces are escaped with {{ and }}. bunt has two additions to that syntax:

Style tags

With {$style_spec}...{/$}, you can apply a style to a section of your string (which can also contain arguments). The start tag {$...} contains the style specification, while the end tag is always {/$}. These tags can also be nested.

bunt::println!("normal color ... {$yellow}Yellow :){/$} ... normal color again");
bunt::println!("{$bold}This is bold. {$red}This is also red!{/$} Just bold again{/$}.");

Each opening tag needs a matching closing one and the other way around.

bunt::println!("{$red}unclosed tag :o");
bunt::println!("{$red}close it once{/$} and close it another time 🙁 {/$}");

Styled arguments

If you want to style an argument, you can use tags right before and after that argument. However, there is also a shorthand syntax: {[style_spec] ...}. You can still use the syntax for named arguments, positional arguments, width, fill/alignmen, precision, formatting traits and everything else from std::fmt after the [...].

// Normal output via `Display`. Equivalent to `"value: {$green}{}{/$}"`
bunt::println!("value: {[green]}", 27);

// Output via `Debug`. All argument formatting syntax from `fmt` works
// inside the braces, after the `[...]`.
bunt::println!("value: {[green]:?}", vec![1, 2, 3]);

// Named argument + precision specified: works.
bunt::println!("value: {[green]foo:.5}", foo = 3.14);

Style specification

bunt has the same capabilities as termcolor. See termcolor::Color and termcolor::ColorSpec for more information. The syntax for style specs in bunt is a simple list of fragments that are joined by +. Examples:

  • red
  • #ff8030+bold
  • yellow+italic+intense
  • bg:white+blue+bold

Full list of allowed fragments:

  • Colors:
    • black, blue, green, red, cyan, magenta, yellow, white
    • RGB as hex string: #rrggbb, e.g. #27ae60
    • 8bit ANSI color codes: with @ and a number between 0 and 255, e.g. @197
  • Background colors: same as colors but prefixed with bg:, e.g. bg:blue or bg:#c0392b
  • Attributes:
    • bold
    • dimmed
    • italic
    • underline
    • intense

bunt macros make sure that your style spec makes sense (only one foreground/background color is allowed, duplicated attributes are not allowed). Invalid style specs result in a compile error.

bunt::println!("{$bold+red+bold}you don't have to say it twice buddy{/$}");

Available macros

  • write and writeln: print to a termcolor::WriteColor instance.
  • print and println: print to stdout.
  • eprint and eprintln: print to stderr.
  • style: parses a format specification and returns the corresponding termcolor::ColorSpec value.

Color Choice

In real applications, you usually want to give your users the choice of color usage, e.g. via a --color CLI argument. If it’s sufficient for you to configure this globally, see set_stdout_color_choice and set_stderr_color_choice. If not, you have to use write[ln] and pass the stream explicitly. By default, ColorChoice::Auto is used.

termcolor already handles the env var NO_COLOR=1 when the color choice is Auto. But it does not automatically detect the presence of a terminal. You likely want that! See here for more details.

Passing multiple format strings (concat! replacement)

In many cases, users wish to call concat! and pass the result as format string to bunt’s macros, e.g. bunt::println!(concat!("foo", "bar")). This is mainly used if you want to write your own macro to wrap bunt’s macros. Unfortunately, this is not easily possible as macros are expaned lazily. See issue #15 for more information.

As a workaround for this fairly common use case, bunt allows passing an “array of format strings”, like so:

bunt::println!(["foo ", "{[red]} bar"], 27);

All given strings will be concatenated by bunt. So the above code is equivalent to bunt::println!("foo {[red]} bar", 27).

For most users this feature is irrelevant. If possible, pass the format string as single string literal.


pub extern crate termcolor;


Writes formatted data to stderr (with ColorChoice::Auto).
Writes formatted data with newline to stderr (with ColorChoice::Auto).
Writes formatted data to stdout (with ColorChoice::Auto).
Writes formatted data with newline to stdout (with ColorChoice::Auto).
Parses the given style specification string and returns the corresponding termcolor::ColorSpec value.
Writes formatted data to a termcolor::WriteColor target.
Writes formatted data with newline to a termcolor::WriteColor target.


Sets the global ColorChoice used by eprint[ln].
Sets the global ColorChoice used by print[ln].
Returns the current global ColorChoice used by eprint[ln].
Returns the current global ColorChoice used by print[ln].