App.rs
前のセクションで見たように、小規模な ratatui
アプリケーションの一般的なモデルは、App
またはその名前のバリエーションと呼ばれる 1 つのアプリケーション状態構造体を持つことです。このパラダイムをこのアプリケーションでも使用します。
この構造体にはすべての「永続的な」データが含まれ、アプリケーションの現在の状態を知る必要があるすべての関数に渡されます。
アプリケーションモード
アプリケーションが入る可能性のあるいくつかの「モード」について考えることは便利です。「モード」で考えると、ウィンドウが描かれているもの、キーバインドが聞くものまで、すべてを簡単に分離できます。
アプリケーションの状態を使用して、2つのことを追跡します。
- ユーザーが見ている画面、
- 強調表示するボックス、「キー」または「値」 (これは、ユーザーがキーと値のペアを編集している場合にのみ適用されます)。
現在の画面列
このチュートリアルアプリケーションでは、3つの「画面」があります。
メイン
: 過去に入力されたすべてのキーと値のペアを表示するメインの概要画面編集
: ユーザーが新しいキーと値のペアを作成するときに表示される画面終了
: ユーザーが入力したキーと値のペアを出力するかどうかを尋ねるプロンプトを表示します。
これらの可能なモードを簡単な列挙で表します。
pub enum CurrentScreen { Main, Editing, Exiting,}
現在の編集列挙
すでにご存知かもしれませんが、ratatui
は画面を自動的に再描画しません1。ratatui
は、最後のフレームで描画したものについても何も記憶しません。
つまり、プログラマーはすべての状態を処理し、ウィジェットを更新して変更を反映させる責任があります。この場合、Editing
モードでユーザーが 2 つの文字列 (キーと値) を入力できるようにします。プログラマーは、ユーザーが編集しようとしているものを把握する責任があります。
この目的のために、ユーザーが現在どのフィールドを入力しているのかを追跡するために、CurrentlyEditing
というアプリケーション状態の別の列挙型を作成します。
pub enum CurrentlyEditing { Key, Value,}
アプリケーションの完全な状態
ユーザーがどこにいるかを追跡するのに役立つ列挙ができるようになったので、必要な場所に渡すことができるこのデータを実際に保存する構造体を作成します。
pub struct App { pub key_input: String, // the currently being edited json key. pub value_input: String, // the currently being edited json value. pub pairs: HashMap<String, String>, // The representation of our key and value pairs with serde Serialize support pub current_screen: CurrentScreen, // the current screen the user is looking at, and will later determine what is rendered. pub currently_editing: Option<CurrentlyEditing>, // the optional state containing which of the key or value pair the user is editing. It is an option, because when the user is not directly editing a key-value pair, this will be set to `None`.}
ヘルパー機能
単に価値の保有者としてアプリケーションを保持することはできますが、他の場所で私たちの生活を楽にするいくつかのヘルパー関数を作成することもできます。もちろん、これらの機能はアプリケーションの状態自体にのみ影響し、それ以外のものはありません。
new()
この関数を追加するのは、単に状態の作成を容易にするためです。これは、変数のインスタンス化ですべてを指定することによって回避できますが、ここで行うことで、状態のユニバーサル デフォルトを簡単に変更できます。
impl App { pub fn new() -> App { App { key_input: String::new(), value_input: String::new(), pairs: HashMap::new(), current_screen: CurrentScreen::Main, currently_editing: None, } } // --snip--
save_key_value()
この関数は、ユーザーがエディターでキーと値のペアを保存するときに呼び出されます。保存された 2 つの変数をキーと値のペア HashMap
に追加し、すべての編集変数のステータスをリセットします。
// --snip-- pub fn save_key_value(&mut self) { self.pairs .insert(self.key_input.clone(), self.value_input.clone());
self.key_input = String::new(); self.value_input = String::new(); self.currently_editing = None; } // --snip--
toggle_editing()
単純なロジックを便利な機能に簡単に配置する方が簡単な場合があるため、メインコードブロックで心配する必要はありません。 toggle_editing
はそのようなケースの1つです。私たちがしているのは、現在編集中かどうか、そしてそれがそうであるかどうかを確認することだけで、キーフィールドとバリューフィールドの編集の間に交換します。
// --snip-- pub fn toggle_editing(&mut self) { if let Some(edit_mode) = &self.currently_editing { match edit_mode { CurrentlyEditing::Key => self.currently_editing = Some(CurrentlyEditing::Value), CurrentlyEditing::Value => self.currently_editing = Some(CurrentlyEditing::Key), }; } else { self.currently_editing = Some(CurrentlyEditing::Key); } } // --snip--
print_json()
最後に、すべてのキー価値ペアからシリアル化されたJSONを表示するもう1つの利便性機能です。
// --snip-- pub fn print_json(&self) -> serde_json::Result<()> { let output = serde_json::to_string(&self.pairs)?; println!("{}", output); Ok(()) } // --snip--
Footnotes
-
ratatui では、フレームごとに UI が新たに描画されます。詳細については、レンダリング セクションを参照してください。 ↩