わたすけです。
皆さん、Rustは好きですか?わたしはすきです。
きっとTUIも好きでしょう。
今回は、RustでTUIを作るために役立つtui-rsを紹介します。
tui-rsとは
tui-rsはRustでTUIを簡単に構築できるライブラリです。crossterm(もしくはtermion)をバックエンドとして、TUIでよくあるウィンドウのような表示はもちろん、キーボード入力を扱うこともできます。
とりあえずREADMEにあるGIFを見ると良いと思います。
使い方
ドキュメントにあることが全てです。Rustはドキュメント見れば書けます(要出典)。とりあえずサンプルを貼り付けて、具体的に何をしているのか見てみましょう。
use std::{io, thread, time::Duration};
use tui::{
backend::CrosstermBackend,
widgets::{Widget, Block, Borders},
layout::{Layout, Constraint, Direction},
Terminal
};
use crossterm::{
event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode},
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
fn main() -> Result<(), io::Error> {
// setup terminal
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
terminal.draw(|f| {
let size = f.size();
let block = Block::default()
.title("Block")
.borders(Borders::ALL);
f.render_widget(block, size);
})?;
thread::sleep(Duration::from_millis(5000));
// restore terminal
disable_raw_mode()?;
execute!(
terminal.backend_mut(),
LeaveAlternateScreen,
DisableMouseCapture
)?;
terminal.show_cursor()?;
Ok(())
}
ブログのハイライト機能にRustがなくて寂しい見た目になっていますが、ターミナルに描画してから5000ms待って終了するだけのシンプルなプログラムです。main関数を見ていきましょう。
ターミナルのセットアップ
enable_raw_mode()
で、ターミナルをraw modeにします。次に、stdoutを持ってきて、execute!
マクロでコマンドを実行しています。そして、crosstermのバックエンドを作成して、tui-rsのTerminalを作成します。
このあたりは(最後のTerminal生成を除いて)ぜんぶcrosstermが提供しているものなので、おまじない程度に捉えてよいでしょう。詳しく知りたければcrosstermのドキュメントを見れば良いと思います。
Terminalを作ったら、draw関数を呼び出します。これに関数(クロージャ)を渡すことによってUIを描画していくことになります。
引数となっているfはFrame型です。
このサンプルでは、”Block” というタイトルが付与されているボーダー付きのBlock(Widgetの一種)を作って、それをレンダリングしています。
これが終わったら、Rust標準ライブラリのthread::sleapを呼んで、5000ms待ちます。
待機が終わったら、raw modeを終了し、executeマクロで後処理を行って、終わりです。
まだ他にもある機能たち
他にも様々な機能があります。例えば、今回はBlockというWidgetを使いましたが、他にもTabs・List・Paragraphといった基本的なWidgetから、SparklineやBarChartといった便利そうなWidgetまでたくさんあります。かなり色々なことができそうです。
また、今回は画面全体にBlockを表示しましたが、Layoutというものを使えば、複数のWidgetをタイル状に並べることができます。exampleが参考になります。というかexampleは全部面白いので、一通り見てみるのが良いと思います。
終わりに
かなり前にNcursesのRustラッパみたいなライブラリを使ったことがあるのですが、それよりも格段に書きやすくて驚きました。
ちなみに、以下のリポジトリは自分が最近開発しているもので、複数のスクリプトを起動し、横に並べて表示できるというものです。そもそもRustが便利なので、複数スレッドでスクリプトを動かして、出力をTUIで並べる・・・みたいなプログラムが簡単にかけるのが良いですね。
というわけで、今後もRustで色々作っていこうと思います。
コメント