Don't Repeat Yourself

Don't Repeat Yourself (DRY) is a principle of software development aimed at reducing repetition of all kinds. -- wikipedia

ターミナルに色をつけられる crate 「ansi_term」

Rust を書いてる際にコンソールでいろいろ出力を出して遊びたいことがあると思います(?).コンソールの出力にふと色をつけたくなって,コンソール文字列の色づけって Rust ではどうやってつけることができるんだろう?と思って調べたらこういう crate がありました.

ansi_term https://crates.io/crates/ansi_term

そもそも UNIX 等でターミナル上の文字列に色をつける際,どのようにして実現しているのかを知らなかったのですが,ANSIエスケープシーケンスというものを用いて色付け等ができるのだそうです.たまに操作ミスって [A とかでてくるあいつですね.

en.wikipedia.org

この仕組を使ったアートまで存在するとか.表現力豊かなんですね.

en.wikipedia.org

さて話がそれてしまいましたが,仕事で使ってみたので知見を放流しておきたいと思います.便利クレート特集.

なおリポジトリはこちらです.

github.com

色づけしてみる

実際にエラーメッセージに色をつけてみます.

use ansi_term::Colour;

fn main() {
    eprintln!("{}", Colour::Red.paint("エラーが発生しましたよ"));
}

すると,エラーメッセージがちゃんと赤く色付けされました.

f:id:yuk1tyd:20190713121837p:plain

次に,ドキュメントを読むと一部だけ文字色を変えられるようなので変えてみましょう.

use ansi_term::Colour;

fn main() {
    println!("一部の色だけを変えてみる: {}", Colour::Yellow.paint("色変わってますか??"));
}

結果は

f:id:yuk1tyd:20190713115104p:plain

ToString を use しておけば,先に文字列を作ってそれを println! 内で使用するといった使い方ももちろんできます.

使用可能な色についてですが,標準で黒や赤,黄色などが用意されている上に,標準の256色を番号指定で利用可能な他,RGB 値で自分の好きな色を指定できます.enum の定義をちょっと見てみましょう.

pub enum Colour {

    /// Colour #0 (foreground code `30`, background code `40`).
    ///
    /// This is not necessarily the background colour, and using it as one may
    /// render the text hard to read on terminals with dark backgrounds.
    Black,

    /// Colour #1 (foreground code `31`, background code `41`).
    Red,

    /// Colour #2 (foreground code `32`, background code `42`).
    Green,

    /// Colour #3 (foreground code `33`, background code `43`).
    Yellow,

    /// Colour #4 (foreground code `34`, background code `44`).
    Blue,

    /// Colour #5 (foreground code `35`, background code `45`).
    Purple,

    /// Colour #6 (foreground code `36`, background code `46`).
    Cyan,

    /// Colour #7 (foreground code `37`, background code `47`).
    ///
    /// As above, this is not necessarily the foreground colour, and may be
    /// hard to read on terminals with light backgrounds.
    White,

    /// A colour number from 0 to 255, for use in 256-colour terminal
    /// environments.
    ///
    /// - Colours 0 to 7 are the `Black` to `White` variants respectively.
    ///   These colours can usually be changed in the terminal emulator.
    /// - Colours 8 to 15 are brighter versions of the eight colours above.
    ///   These can also usually be changed in the terminal emulator, or it
    ///   could be configured to use the original colours and show the text in
    ///   bold instead. It varies depending on the program.
    /// - Colours 16 to 231 contain several palettes of bright colours,
    ///   arranged in six squares measuring six by six each.
    /// - Colours 232 to 255 are shades of grey from black to white.
    ///
    /// It might make more sense to look at a [colour chart][cc].
    ///
    /// [cc]: https://upload.wikimedia.org/wikipedia/en/1/15/Xterm_256color_chart.svg
    Fixed(u8),

    /// A 24-bit RGB color, as specified by ISO-8613-3.
    RGB(u8, u8, u8),
}

文字列への装飾もできる

太字や下線もできます.

use ansi_term::{Colour, Style};

fn main() {
    println!(
        "{}そして,{}",
        Style::new().underline().paint("下線引けていますか?"),
        Style::new().bold().paint("太字になっていますか?")
    );
}

f:id:yuk1tyd:20190713115819p:plain

まとめ

  • コンソールの文字列に色をつけられるクレートがあるよ.
  • 一般的なコンソールの色付けは ANSI エスケープシーケンスという仕組みを使って実現されているよ.