terminal_style 0.5.0

A minimal library for styling terminal text using ANSI escape codes.
Documentation

terminal_style

A minimal Rust library for styling terminal text using ANSI escape codes. Supports 24-bit TrueColor (RGB) as its primary format, alongside 256-color (8-bit) ANSI quantization. Easily apply foreground/background colors from hex, RGB, or ANSI 8-bit values to strings, 1D vectors, and 2D vectors. Perfect for simple CLI tools.

Installation

terminal_style is published as a crate on crates.io.

cargo add terminal_style

Features

  • 24-bit TrueColor (RGB) support for smooth gradients
  • 8-bit ANSI quantization for legacy terminal support
  • Convert RGB or Hex to ANSI 256-color
  • Apply foreground/background color to strings, vectors, and 2D vectors
  • Format text as bold, italic, faint, inverse, or underline
  • Graceful handling of invalid color inputs

Usage

Formatting functions work with strings, vectors, and 2D vectors of strings seamlessly. It also supports references, so you can pass either owned or borrowed values.

Color Depth Options

terminal_style provides two sets of functions for color styling:

  • color / background: Aliases for color_rgb / background_rgb. Unconditionally generates 24-bit TrueColor sequences.
  • color_ansi / background_ansi: Quantizes any color input to the nearest 8-bit ANSI index (256-color palette).
use terminal_style::format::{color_rgb, color_ansi};

// 24-bit TrueColor: \x1b[38;2;255;20;147m
let rgb = color_rgb("#FF1493", "Deep Pink")?;

// 8-bit ANSI: \x1b[38;5;198m
let ansi = color_ansi("#FF1493", "Deep Pink")?;

Supported Input Types

Input Type Output Type Description
String String Single string formatting
&str String Single string formatting
&String String Reference forwarding to String
Vec<String> Vec<String> Format each element individually
&Vec<String> Vec<String> Reference forwarding to owned Vec<String>
Vec<Vec<String>> Vec<Vec<String>> Format every element in each subvector
&Vec<Vec<String>> Vec<Vec<String>> Reference forwarding to owned Vec<Vec<String>>

Example


use terminal_style::{
    format::{bold, underline, color, background, color_ansi},
    color::ColorConversionError,
};

fn main() -> Result<(), ColorConversionError> {
    // --- Single string styling ---
    let text = "Styled!";

    // Using `?` to propagate errors if color conversion fails
    // By default, `color` and `background` use 24-bit TrueColor
    let fg = color("#FF1493", text)?;       // Foreground color (pink)
    let bg = background("#8257AD", text)?;  // Background color (lavender)
    let bolded = bold(fg.clone());          // Bold formatting

    println!("FG: {}", fg);
    println!("BG: {}", bg);
    println!("Bold: {}", bolded);

    // Explicitly use 8-bit ANSI for legacy terminals
    let legacy = color_ansi([0, 255, 0], "I am 8-bit Green")?;
    println!("{}", legacy);

    // --- 1D vector of strings ---
    let texts_1d = vec!["Red".to_string(), "Green".to_string(), "Blue".to_string()];
    let colored_1d = color([255, 0, 0], texts_1d.clone())?;  // Red foreground
    let bolded_1d = bold(texts_1d.clone());

    println!("\n1D Colored vector (TrueColor):");
    for line in &colored_1d {
        println!("{}", line);
    }

    // --- 2D vector of strings ---
    let texts_2d = vec![
        vec!["A".to_string(), "B".to_string()],
        vec!["C".to_string(), "D".to_string()],
    ];

    let bolded_2d: Vec<Vec<String>> = bold(texts_2d.clone());
    let bg_colored_2d = background([255, 105, 180], texts_2d.clone())?; // Pink background
    let bold_underline_bg_2d = bold(underline(bg_colored_2d.clone()));

    // Output demo omitted for brevity...

    Ok(())
}

Color Conversion Examples

Utility functions enable converting between RGB, HEX, and ANSI 8-bit values.

use terminal_style::color::*;

fn main() {
    // RGB to Hex
    assert_eq!(rgb_to_hex([255, 165, 0]), "#FFA500");

    // Hex to RGB
    assert_eq!(hex_to_rgb("#00FF00"), [0, 255, 0]);

    // RGB to ANSI
    assert_eq!(rgb_to_ansi8([255, 0, 0]), 196);

    // Hex to ANSI
    assert_eq!(hex_to_ansi8("0000FF"), 21);

    // ANSI to RGB
    assert_eq!(ansi8_to_rgb(196), [255, 0, 0]);

    // ANSI to HEX
    assert_eq!(ansi8_to_hex(196), "#FF0000"); // Red
}

Additional examples in the examples folder.

Tests

cargo test

Structure

  • color/: Utility color conversions (hex, rgb, ansi)
  • format/: Terminal text styling functions
  • tests/: Test suite
  • examples/: Usage examples

Authors

Ron Ilan

License

MIT

Coded in Rust with a little help from the LLMs. Based on the lovingly handcrafted colors.crumb.. Derived from work done on Impossible.js. Enjoy.

Fabriqué au Canada : Made in Canada 🇨🇦