A Real TUI with ratatui
Draw widgets, handle key events, and run a proper render loop.
cargo add ratatui crossterm
A ratatui app is a loop with three steps: draw the current state, wait for an event, update the state.
let mut terminal = ratatui::init();
loop {
terminal.draw(|frame| {
let block = Block::bordered().title("Guess (1-100)");
frame.render_widget(Paragraph::new(input.as_str()).block(block), frame.area());
})?;
if let Event::Key(key) = event::read()? {
match key.code {
KeyCode::Char(c) if c.is_ascii_digit() => input.push(c),
KeyCode::Backspace => { input.pop(); }
KeyCode::Enter => submit(&mut game, &mut input),
KeyCode::Esc => break,
_ => {}
}
}
}
ratatui::restore();
The ratatui::restore() call matters β if you exit without it, the userβs terminal is left
in raw mode. Wrap it in a guard type with a Drop impl if your app can panic.