Build the Mutt-style TUI shell and action model

This commit is contained in:
Hermes Agent
2026-08-10 05:46:32 +00:00
parent f03fdc063c
commit 42e6a82b2d
7 changed files with 1051 additions and 42 deletions

View File

@@ -3,47 +3,10 @@
use std::io;
use crossterm::event::{self, Event, KeyCode};
use ratatui::{
DefaultTerminal, Frame,
widgets::{Block, Paragraph},
};
fn main() -> io::Result<()> {
ratatui::run(run)
}
fn run(terminal: &mut DefaultTerminal) -> io::Result<()> {
loop {
terminal.draw(draw)?;
if let Event::Key(key) = event::read()?
&& is_quit(key.code)
{
return Ok(());
}
}
}
fn draw(frame: &mut Frame) {
frame.render_widget(
Paragraph::new("No password store is open. Press q to quit.")
.block(Block::bordered().title(ironstorage::PRODUCT_NAME)),
frame.area(),
);
}
fn is_quit(key: KeyCode) -> bool {
matches!(key, KeyCode::Char('q') | KeyCode::Esc)
}
#[cfg(test)]
mod tests {
use crossterm::event::KeyCode;
#[test]
fn q_and_escape_quit() {
assert!(super::is_quit(KeyCode::Char('q')));
assert!(super::is_quit(KeyCode::Esc));
assert!(!super::is_quit(KeyCode::Enter));
}
ironstorage_tui::terminal::run(
ratatui::try_init,
ratatui::try_restore,
ironstorage_tui::run,
)
}