diff --git a/src/main.rs b/src/main.rs index 8cf1985..040678d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ mod persistence; mod ui; mod view; -use std::io; +use std::io::{self, Stdout}; use std::path::PathBuf; use std::time::Duration; @@ -202,7 +202,7 @@ fn parse_args(args: Vec) -> Box { } fn get_initial_model(file_path: &Option) -> Result { - return if let Some(ref path) = file_path { + if let Some(ref path) = file_path { if path.exists() { let mut m = persistence::load(path) .with_context(|| format!("Failed to load {}", path.display()))?; @@ -218,7 +218,29 @@ fn get_initial_model(file_path: &Option) -> Result { } } else { Ok(Model::new("New Model")) - }; + } +} + +struct TuiGuard<'a> { + terminal: Terminal>, +} + +impl<'a> TuiGuard<'a> { + fn enter(out: &'a mut Stdout) -> Result { + enable_raw_mode()?; + execute!(out, EnterAlternateScreen)?; + let backend = CrosstermBackend::new(out); + let terminal = Terminal::new(backend)?; + + Ok(Self { terminal }) + } +} + +impl<'a> Drop for TuiGuard<'a> { + fn drop(&mut self) { + let _ = execute!(self.terminal.backend_mut(), LeaveAlternateScreen); + let _ = disable_raw_mode(); + } } fn run_tui( @@ -226,11 +248,8 @@ fn run_tui( file_path: Option, import_json: Option, ) -> Result<()> { - enable_raw_mode()?; let mut stdout = io::stdout(); - execute!(stdout, EnterAlternateScreen)?; - let backend = CrosstermBackend::new(stdout); - let mut terminal = Terminal::new(backend)?; + let mut tui_context = TuiGuard::enter(&mut stdout)?; let mut app = App::new(model, file_path); if let Some(json) = import_json { @@ -238,7 +257,7 @@ fn run_tui( } loop { - terminal.draw(|f| draw(f, &app))?; + tui_context.terminal.draw(|f| draw(f, &app))?; if event::poll(Duration::from_millis(100))? { if let Event::Key(key) = event::read()? { @@ -253,8 +272,6 @@ fn run_tui( } } - disable_raw_mode()?; - execute!(terminal.backend_mut(), LeaveAlternateScreen)?; Ok(()) }