vte
from エスケープシーケンス
Alacritty プロジェクトから生まれた Rust 製の VTパーサークレート。
https://github.com/alacritty/vte
特徴
Paul Williamsの状態遷移図を忠実に実装
テーブル駆動型の状態遷移(ルックアップテーブルによる高速化)
パーサーとセマンティクスの分離が明確(Perform トレイトを実装するだけ)
no_std対応可能
API概要
code:rust
// Cargo.toml
// dependencies
// vte = "0.13"
use vte::{Parser, Perform};
struct MyHandler;
impl Perform for MyHandler {
fn print(&mut self, c: char) {
// 通常文字の出力
println!("print: {:?}", c);
}
fn execute(&mut self, byte: u8) {
// C0制御文字の処理
println!("execute: 0x{:02X}", byte);
}
fn csi_dispatch(
&mut self,
params: &vte::Params,
intermediates: &u8,
ignore: bool,
action: char,
) {
// CSIシーケンスの処理
println!("CSI: params={:?}, action={}", params, action);
// 例: \x1b[31m → params=31, action='m'
// 例: \x1b[38;5;196m → params=38], 5, [196, action='m'
}
fn osc_dispatch(&mut self, params: &[&u8], bell_terminated: bool) {
// OSCシーケンスの処理
// 例: \x1b]0;title\x07
// → params0 = b"0", params1 = b"title"
println!("OSC: {:?}", params);
}
fn esc_dispatch(&mut self, intermediates: &u8, ignore: bool, byte: u8) {
// ESCシーケンスの処理
println!("ESC: byte=0x{:02X}", byte);
}
fn hook(&mut self, params: &vte::Params, intermediates: &u8, ignore: bool, action: char) {
// DCS開始
}
fn unhook(&mut self) {
// DCS終了
}
fn put(&mut self, byte: u8) {
// DCSデータ
}
}
fn main() {
let mut parser = Parser::new();
let mut handler = MyHandler;
let input = b"\x1b[31mHello\x1b[0m World\n";
for &byte in input {
parser.advance(&mut handler, byte);
}
}
長所
Rust のメモリ安全性
ゼロアロケーションのパーサー(ホットパスでヒープ割り当てなし)
Alacritty で実戦投入されているため信頼性が高い
Params イテレータが ; と : の両方のサブパラメータに対応
短所
パーサーのみ提供(セマンティクスの解釈は自分で実装する必要がある)
ターミナルグリッド・スクロールバッファ等の上位レイヤーは含まない
ドキュメントが最小限