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;
use termion::screen::*;
use termion::screen::IntoAlternateScreen;
use std::io::{Write, stdout};
use std::{time, thread};
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();
screen.flush().unwrap();

View File

@ -3,7 +3,7 @@ extern crate termion;
use termion::event::Key;
use termion::input::TermRead;
use termion::raw::IntoRawMode;
use termion::screen::*;
use termion::screen::{IntoAlternateScreen, ToAlternateScreen, ToMainScreen};
use std::io::{Write, stdout, stdin};
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() {
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_alt_screen_msg(&mut screen);

View File

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