Skip to Content
Course content

204: Colored Terminal Output

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I've always found that plain white text in a terminal is a nightmare for debugging. When you're scanning through hundreds of lines of logs, your eyes just glaze over. That's why I always integrate color into my CLI tools as early as possible. It transforms a wall of text into something scannable, where a red "ERROR" actually jumps out at you.

In Rust, you could manually print ANSI escape codes—those weird strings like \x1b[31m—but that's a recipe for a headache. Instead, I use the colored crate. It's lightweight and provides a very intuitive extension trait that lets you call methods like .red() or .bold() directly on strings.

Adding the dependency

First, let's get the crate into our project. I'm going to build a small "System Health Monitor" that reports the status of different services. Run this in your terminal:

cargo add colored

Setting up our Health Monitor

I want to represent different service states using an enum. This keeps our logic clean. I'll start by importing Colorize, which is the trait that actually adds the coloring methods to our strings.

use colored::*;

enum ServiceStatus {
    Online,
    Degraded,
    Offline,
}

fn main() {
    let services = vec![
        ("Database", ServiceStatus::Online),
        ("Cache", ServiceStatus::Degraded),
        ("Auth-API", ServiceStatus::Offline),
    ];

    for (name, status) in services {
        print_status(name, status);
    }
}

The "Type Mismatch" stumble

Now, here is where I usually trip up when I'm rushing. I want to print the status in a color that matches its meaning. I'll try to call .green() or .red() directly on the enum variant. Let's see what happens:

fn print_status(name: &str, status: ServiceStatus) {
    // I'll try to color the status directly here
    match status {
        ServiceStatus::Online => println!("{}: {}", name, status.green()),
        ServiceStatus::Degraded => println!("{}: {}", name, status.yellow()),
        ServiceStatus::Offline => println!("{}: {}", name, status.red()),
    }
}

If you try to compile this, the compiler is going to scream at you. Why? Because ServiceStatus is an enum, not a string. The colored crate extends String and &str, but it has no idea what to do with my custom ServiceStatus type. I forgot that I need to turn the status into a string first.

Fixing the logic and polishing

To fix this, I'll derive Debug on my enum so I can easily turn it into a string using the format! macro. This is the fastest way to get the variant name as a string without writing a manual Display implementation.

#[derive(Debug)]
enum ServiceStatus {
    Online,
    Degraded,
    Offline,
}

fn print_status(name: &str, status: ServiceStatus) {
    // We format the enum into a string first, THEN call the color method
    match status {
        ServiceStatus::Online => {
            println!("{}: {}", name, format!("{:?}", status).green().bold());
        }
        ServiceStatus::Degraded => {
            println!("{}: {}", name, format!("{:?}", status).yellow());
        }
        ServiceStatus::Offline => {
            println!("{}: {}", name, format!("{:?}", status).red().underline());
        }
    }
}

I added .bold() and .underline() just to show how you can chain these modifiers. Now, when you run this, the "Online" status is a bold green, "Degraded" is yellow, and "Offline" is a red underlined warning. It's a small change, but the difference in readability is massive.




📋 Practical Task

Build a Color-Coded Log Parser

Create a program that simulates reading a log file. Define a list of strings where some lines start with [INFO], some with [WARN], and some with [ERROR].

  • Use the colored crate to print the lines to the terminal.
  • [INFO] lines should be blue.
  • [WARN] lines should be yellow.
  • [ERROR] lines should be red and bold.
  • Any line that doesn't match those prefixes should be printed in the default terminal color.

Hint: Use .starts_with() to check the beginning of each log line before applying the color.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.