Improve error handling in the `raw` and `screen` modules

- Ignore errors in `Drop` implementations.
- Replace `AlternateScreen::from` with an `IntoAlternateScreen` trait
  which doesn't panic on errors, to make the API more consistent with
  the `raw` module.
This commit is contained in:
Lassi Pulkkinen 2021-06-08 19:59:01 +03:00
parent dce5e7500f
commit 5d08b65b57
No known key found for this signature in database
GPG Key ID: 01FD492E0E0055CF
4 changed files with 18 additions and 14 deletions

View File

@ -1,12 +1,12 @@
extern crate termion; extern crate termion;
use termion::screen::*; use termion::screen::IntoAlternateScreen;
use std::io::{Write, stdout}; use std::io::{Write, stdout};
use std::{time, thread}; use std::{time, thread};
fn main() { fn main() {
{ {
let mut screen = AlternateScreen::from(stdout()); let mut screen = stdout().into_alternate_screen().unwrap();
write!(screen, "Welcome to the alternate screen.\n\nPlease wait patiently until we arrive back at the main screen in a about three seconds.").unwrap(); write!(screen, "Welcome to the alternate screen.\n\nPlease wait patiently until we arrive back at the main screen in a about three seconds.").unwrap();
screen.flush().unwrap(); screen.flush().unwrap();

View File

@ -3,7 +3,7 @@ extern crate termion;
use termion::event::Key; use termion::event::Key;
use termion::input::TermRead; use termion::input::TermRead;
use termion::raw::IntoRawMode; use termion::raw::IntoRawMode;
use termion::screen::*; use termion::screen::{IntoAlternateScreen, ToAlternateScreen, ToMainScreen};
use std::io::{Write, stdout, stdin}; use std::io::{Write, stdout, stdin};
fn write_alt_screen_msg<W: Write>(screen: &mut W) { fn write_alt_screen_msg<W: Write>(screen: &mut W) {
@ -16,7 +16,7 @@ fn write_alt_screen_msg<W: Write>(screen: &mut W) {
fn main() { fn main() {
let stdin = stdin(); let stdin = stdin();
let mut screen = AlternateScreen::from(stdout().into_raw_mode().unwrap()); let mut screen = stdout().into_raw_mode().unwrap().into_alternate_screen().unwrap();
write!(screen, "{}", termion::cursor::Hide).unwrap(); write!(screen, "{}", termion::cursor::Hide).unwrap();
write_alt_screen_msg(&mut screen); write_alt_screen_msg(&mut screen);

View File

@ -42,7 +42,7 @@ pub struct RawTerminal<W: Write> {
impl<W: Write> Drop for RawTerminal<W> { impl<W: Write> Drop for RawTerminal<W> {
fn drop(&mut self) { fn drop(&mut self) {
set_terminal_attr(&self.prev_ios).unwrap(); let _ = set_terminal_attr(&self.prev_ios);
} }
} }

View File

@ -6,12 +6,12 @@
//! # Example //! # Example
//! //!
//! ```rust //! ```rust
//! use termion::screen::AlternateScreen; //! use termion::screen::IntoAlternateScreen;
//! use std::io::{Write, stdout}; //! use std::io::{Write, stdout};
//! //!
//! fn main() { //! fn main() {
//! { //! {
//! let mut screen = AlternateScreen::from(stdout()); //! let mut screen = stdout().into_alternate_screen().unwrap();
//! write!(screen, "Writing to alternate screen!").unwrap(); //! write!(screen, "Writing to alternate screen!").unwrap();
//! screen.flush().unwrap(); //! screen.flush().unwrap();
//! } //! }
@ -51,18 +51,22 @@ pub struct AlternateScreen<W: Write> {
output: W, output: W,
} }
impl<W: Write> AlternateScreen<W> { /// Extension trait for writers, providing the `into_alternate_screen` function.
/// Create an alternate screen wrapper struct for the provided output and switch the terminal pub trait IntoAlternateScreen: Write + Sized {
/// to the alternate screen. /// Switch the terminal controlled by this writer to use the alternate screen. The terminal will be
pub fn from(mut output: W) -> Self { /// restored to the main screen when the `AlternateScreen` returned by this function is
write!(output, "{}", ToAlternateScreen).expect("switch to alternate screen"); /// dropped.
AlternateScreen { output: output } fn into_alternate_screen(mut self) -> io::Result<AlternateScreen<Self>> {
write!(self, "{}", ToAlternateScreen)?;
Ok(AlternateScreen { output: self })
} }
} }
impl<W: Write> IntoAlternateScreen for W {}
impl<W: Write> Drop for AlternateScreen<W> { impl<W: Write> Drop for AlternateScreen<W> {
fn drop(&mut self) { fn drop(&mut self) {
write!(self, "{}", ToMainScreen).expect("switch to main screen"); let _ = write!(self, "{}", ToMainScreen);
} }
} }