refactor: move terminal guard to own file

This commit is contained in:
Lukas Wölfer
2026-01-24 08:50:06 +01:00
parent 15c792fc21
commit 0081e79492
2 changed files with 34 additions and 32 deletions

View File

@@ -1,45 +1,18 @@
use std::io::{self, Read}; use std::io::{self, Read};
use std::time::Duration; use std::time::Duration;
use crossterm::cursor::Show;
use crossterm::event::{self, Event, KeyCode}; use crossterm::event::{self, Event, KeyCode};
use crossterm::execute; use crossterm::execute;
use crossterm::terminal::{ use crossterm::terminal::{EnterAlternateScreen, enable_raw_mode};
EnterAlternateScreen, LeaveAlternateScreen, disable_raw_mode, enable_raw_mode,
};
use ratatui::Terminal; use ratatui::Terminal;
use ratatui::backend::CrosstermBackend; use ratatui::backend::CrosstermBackend;
use ratatui::layout::{Constraint, Direction, Layout}; use ratatui::layout::{Constraint, Direction, Layout};
use ratatui::style::Style; use ratatui::style::Style;
use ratatui::widgets::{Block, Borders, List, ListItem, ListState}; use ratatui::widgets::{Block, Borders, List, ListItem, ListState};
// RAII guard to ensure terminal is restored on panic/unwind mod terminal_guard;
struct TerminalModeGuard { use terminal_guard::TerminalModeGuard;
// track whether we still need to clean up
active: bool,
}
impl TerminalModeGuard {
fn new() -> Self {
TerminalModeGuard { active: true }
}
fn cleanup(&mut self) {
if !self.active {
return;
}
let _ = disable_raw_mode();
let mut stdout = std::io::stdout();
let _ = execute!(stdout, LeaveAlternateScreen, Show);
self.active = false;
}
}
impl Drop for TerminalModeGuard {
fn drop(&mut self) {
self.cleanup();
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> { fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut input = String::new(); let mut input = String::new();
io::stdin().read_to_string(&mut input)?; io::stdin().read_to_string(&mut input)?;
@@ -78,8 +51,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.iter() .iter()
.enumerate() .enumerate()
.map(|(i, l)| { .map(|(i, l)| {
let prefix = if marked[i] { "[x]" } else { "[ ]" }; let prefix = if marked[i] { 'x' } else { ' ' };
ListItem::new(format!("{} {}", prefix, l)) ListItem::new(format!("[{prefix}] {l}"))
}) })
.collect(); .collect();

29
src/terminal_guard.rs Normal file
View File

@@ -0,0 +1,29 @@
use crossterm::cursor::Show;
use crossterm::execute;
use crossterm::terminal::{LeaveAlternateScreen, disable_raw_mode};
pub struct TerminalModeGuard {
active: bool,
}
impl TerminalModeGuard {
pub fn new() -> Self {
Self { active: true }
}
pub fn cleanup(&mut self) {
if !self.active {
return;
}
let _ = disable_raw_mode();
let mut stdout = std::io::stdout();
let _ = execute!(stdout, LeaveAlternateScreen, Show);
self.active = false;
}
}
impl Drop for TerminalModeGuard {
fn drop(&mut self) {
self.cleanup();
}
}