Skip to content

Commit 372e82c

Browse files
committed
Auto merge of #29999 - SingingTree:libterm_unwrapping, r=alexcrichton
This removes a number of instances of unwrap and replaces them with pattern matching. This is in response to rust issue #29992.
2 parents 7540dcd + 0ee230a commit 372e82c

File tree

8 files changed

+545
-698
lines changed

8 files changed

+545
-698
lines changed

src/libsyntax/diagnostic.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use std::cell::{RefCell, Cell};
2020
use std::{cmp, error, fmt};
2121
use std::io::prelude::*;
2222
use std::io;
23-
use term::{self, WriterWrapper};
23+
use term;
2424

2525
/// maximum number of lines we will print for each error; arbitrary.
2626
const MAX_LINES: usize = 6;
@@ -318,7 +318,7 @@ pub struct EmitterWriter {
318318
}
319319

320320
enum Destination {
321-
Terminal(Box<term::Terminal<WriterWrapper> + Send>),
321+
Terminal(Box<term::StderrTerminal>),
322322
Raw(Box<Write + Send>),
323323
}
324324

@@ -365,7 +365,7 @@ impl EmitterWriter {
365365

366366
fn print_maybe_styled(&mut self,
367367
args: fmt::Arguments,
368-
color: term::attr::Attr,
368+
color: term::Attr,
369369
print_newline_at_end: bool) -> io::Result<()> {
370370
match self.dst {
371371
Terminal(ref mut t) => {
@@ -408,13 +408,13 @@ impl EmitterWriter {
408408
try!(write!(&mut self.dst, "{} ", topic));
409409
}
410410

411-
try!(print_maybe_styled!(self, term::attr::ForegroundColor(lvl.color()),
411+
try!(print_maybe_styled!(self, term::Attr::ForegroundColor(lvl.color()),
412412
"{}: ", lvl.to_string()));
413-
try!(print_maybe_styled!(self, term::attr::Bold, "{}", msg));
413+
try!(print_maybe_styled!(self, term::Attr::Bold, "{}", msg));
414414

415415
match code {
416416
Some(code) => {
417-
let style = term::attr::ForegroundColor(term::color::BRIGHT_MAGENTA);
417+
let style = term::Attr::ForegroundColor(term::color::BRIGHT_MAGENTA);
418418
try!(print_maybe_styled!(self, style, " [{}]", code.clone()));
419419
}
420420
None => ()
@@ -646,7 +646,7 @@ impl EmitterWriter {
646646
s.pop();
647647
}
648648

649-
try!(println_maybe_styled!(self, term::attr::ForegroundColor(lvl.color()),
649+
try!(println_maybe_styled!(self, term::Attr::ForegroundColor(lvl.color()),
650650
"{}", s));
651651
}
652652
}
@@ -719,7 +719,7 @@ impl EmitterWriter {
719719
}
720720
}
721721
s.push('^');
722-
println_maybe_styled!(self, term::attr::ForegroundColor(lvl.color()),
722+
println_maybe_styled!(self, term::Attr::ForegroundColor(lvl.color()),
723723
"{}", s)
724724
}
725725

src/libterm/lib.rs

+72-94
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -11,29 +11,28 @@
1111
//! Terminal formatting library.
1212
//!
1313
//! This crate provides the `Terminal` trait, which abstracts over an [ANSI
14-
//! Terminal][ansi] to provide color printing, among other things. There are two implementations,
15-
//! the `TerminfoTerminal`, which uses control characters from a
16-
//! [terminfo][ti] database, and `WinConsole`, which uses the [Win32 Console
14+
//! Terminal][ansi] to provide color printing, among other things. There are two
15+
//! implementations, the `TerminfoTerminal`, which uses control characters from
16+
//! a [terminfo][ti] database, and `WinConsole`, which uses the [Win32 Console
1717
//! API][win].
1818
//!
1919
//! # Examples
2020
//!
2121
//! ```no_run
2222
//! # #![feature(rustc_private)]
2323
//! extern crate term;
24-
//!
2524
//! use std::io::prelude::*;
2625
//!
2726
//! fn main() {
2827
//! let mut t = term::stdout().unwrap();
2928
//!
3029
//! t.fg(term::color::GREEN).unwrap();
31-
//! (write!(t, "hello, ")).unwrap();
30+
//! write!(t, "hello, ").unwrap();
3231
//!
3332
//! t.fg(term::color::RED).unwrap();
34-
//! (writeln!(t, "world!")).unwrap();
33+
//! writeln!(t, "world!").unwrap();
3534
//!
36-
//! t.reset().unwrap();
35+
//! assert!(t.reset().unwrap());
3736
//! }
3837
//! ```
3938
//!
@@ -58,84 +57,60 @@
5857
#![deny(missing_docs)]
5958

6059
#![feature(box_syntax)]
61-
#![feature(rustc_private)]
6260
#![feature(staged_api)]
63-
#![feature(str_char)]
64-
#![feature(vec_push_all)]
6561
#![cfg_attr(windows, feature(libc))]
6662
// Handle rustfmt skips
6763
#![feature(custom_attribute)]
6864
#![allow(unused_attributes)]
6965

70-
#[macro_use]
71-
extern crate log;
66+
use std::io::prelude::*;
7267

7368
pub use terminfo::TerminfoTerminal;
7469
#[cfg(windows)]
7570
pub use win::WinConsole;
7671

77-
use std::io::prelude::*;
78-
use std::io;
72+
use std::io::{self, Stdout, Stderr};
7973

8074
pub mod terminfo;
8175

8276
#[cfg(windows)]
8377
mod win;
8478

85-
/// A hack to work around the fact that `Box<Write + Send>` does not
86-
/// currently implement `Write`.
87-
pub struct WriterWrapper {
88-
wrapped: Box<Write + Send>,
89-
}
90-
91-
impl Write for WriterWrapper {
92-
#[inline]
93-
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
94-
self.wrapped.write(buf)
95-
}
96-
97-
#[inline]
98-
fn flush(&mut self) -> io::Result<()> {
99-
self.wrapped.flush()
100-
}
101-
}
79+
/// Alias for stdout terminals.
80+
pub type StdoutTerminal = Terminal<Output=Stdout> + Send;
81+
/// Alias for stderr terminals.
82+
pub type StderrTerminal = Terminal<Output=Stderr> + Send;
10283

10384
#[cfg(not(windows))]
10485
/// Return a Terminal wrapping stdout, or None if a terminal couldn't be
10586
/// opened.
106-
pub fn stdout() -> Option<Box<Terminal<WriterWrapper> + Send>> {
107-
TerminfoTerminal::new(WriterWrapper { wrapped: box std::io::stdout() })
87+
pub fn stdout() -> Option<Box<StdoutTerminal>> {
88+
TerminfoTerminal::new(io::stdout()).map(|t| Box::new(t) as Box<StdoutTerminal>)
10889
}
10990

11091
#[cfg(windows)]
11192
/// Return a Terminal wrapping stdout, or None if a terminal couldn't be
11293
/// opened.
113-
pub fn stdout() -> Option<Box<Terminal<WriterWrapper> + Send>> {
114-
let ti = TerminfoTerminal::new(WriterWrapper { wrapped: box std::io::stdout() });
115-
116-
match ti {
117-
Some(t) => Some(t),
118-
None => WinConsole::new(WriterWrapper { wrapped: box std::io::stdout() }),
119-
}
94+
pub fn stdout() -> Option<Box<StdoutTerminal>> {
95+
TerminfoTerminal::new(io::stdout())
96+
.map(|t| Box::new(t) as Box<StdoutTerminal>)
97+
.or_else(|| WinConsole::new(io::stdout()).ok().map(|t| Box::new(t) as Box<StdoutTerminal>))
12098
}
12199

122100
#[cfg(not(windows))]
123101
/// Return a Terminal wrapping stderr, or None if a terminal couldn't be
124102
/// opened.
125-
pub fn stderr() -> Option<Box<Terminal<WriterWrapper> + Send>> {
126-
TerminfoTerminal::new(WriterWrapper { wrapped: box std::io::stderr() })
103+
pub fn stderr() -> Option<Box<StderrTerminal>> {
104+
TerminfoTerminal::new(io::stderr()).map(|t| Box::new(t) as Box<StderrTerminal>)
127105
}
128106

129107
#[cfg(windows)]
130108
/// Return a Terminal wrapping stderr, or None if a terminal couldn't be
131109
/// opened.
132-
pub fn stderr() -> Option<Box<Terminal<WriterWrapper> + Send>> {
133-
let ti = TerminfoTerminal::new(WriterWrapper { wrapped: box std::io::stderr() });
134-
135-
match ti {
136-
Some(t) => Some(t),
137-
None => WinConsole::new(WriterWrapper { wrapped: box std::io::stderr() }),
138-
}
110+
pub fn stderr() -> Option<Box<StderrTerminal>> {
111+
TerminfoTerminal::new(io::stderr())
112+
.map(|t| Box::new(t) as Box<StderrTerminal>)
113+
.or_else(|| WinConsole::new(io::stderr()).ok().map(|t| Box::new(t) as Box<StderrTerminal>))
139114
}
140115

141116

@@ -164,43 +139,41 @@ pub mod color {
164139
pub const BRIGHT_WHITE: Color = 15;
165140
}
166141

167-
/// Terminal attributes
168-
pub mod attr {
169-
pub use self::Attr::*;
170-
171-
/// Terminal attributes for use with term.attr().
172-
///
173-
/// Most attributes can only be turned on and must be turned off with term.reset().
174-
/// The ones that can be turned off explicitly take a boolean value.
175-
/// Color is also represented as an attribute for convenience.
176-
#[derive(Copy, Clone)]
177-
pub enum Attr {
178-
/// Bold (or possibly bright) mode
179-
Bold,
180-
/// Dim mode, also called faint or half-bright. Often not supported
181-
Dim,
182-
/// Italics mode. Often not supported
183-
Italic(bool),
184-
/// Underline mode
185-
Underline(bool),
186-
/// Blink mode
187-
Blink,
188-
/// Standout mode. Often implemented as Reverse, sometimes coupled with Bold
189-
Standout(bool),
190-
/// Reverse mode, inverts the foreground and background colors
191-
Reverse,
192-
/// Secure mode, also called invis mode. Hides the printed text
193-
Secure,
194-
/// Convenience attribute to set the foreground color
195-
ForegroundColor(super::color::Color),
196-
/// Convenience attribute to set the background color
197-
BackgroundColor(super::color::Color),
198-
}
142+
/// Terminal attributes for use with term.attr().
143+
///
144+
/// Most attributes can only be turned on and must be turned off with term.reset().
145+
/// The ones that can be turned off explicitly take a boolean value.
146+
/// Color is also represented as an attribute for convenience.
147+
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
148+
pub enum Attr {
149+
/// Bold (or possibly bright) mode
150+
Bold,
151+
/// Dim mode, also called faint or half-bright. Often not supported
152+
Dim,
153+
/// Italics mode. Often not supported
154+
Italic(bool),
155+
/// Underline mode
156+
Underline(bool),
157+
/// Blink mode
158+
Blink,
159+
/// Standout mode. Often implemented as Reverse, sometimes coupled with Bold
160+
Standout(bool),
161+
/// Reverse mode, inverts the foreground and background colors
162+
Reverse,
163+
/// Secure mode, also called invis mode. Hides the printed text
164+
Secure,
165+
/// Convenience attribute to set the foreground color
166+
ForegroundColor(color::Color),
167+
/// Convenience attribute to set the background color
168+
BackgroundColor(color::Color),
199169
}
200170

201171
/// A terminal with similar capabilities to an ANSI Terminal
202172
/// (foreground/background colors etc).
203-
pub trait Terminal<T: Write>: Write {
173+
pub trait Terminal: Write {
174+
/// The terminal's output writer type.
175+
type Output: Write;
176+
204177
/// Sets the foreground color to the given color.
205178
///
206179
/// If the color is a bright color, but the terminal only supports 8 colors,
@@ -222,24 +195,29 @@ pub trait Terminal<T: Write>: Write {
222195
/// Sets the given terminal attribute, if supported. Returns `Ok(true)`
223196
/// if the attribute was supported, `Ok(false)` otherwise, and `Err(e)` if
224197
/// there was an I/O error.
225-
fn attr(&mut self, attr: attr::Attr) -> io::Result<bool>;
198+
fn attr(&mut self, attr: Attr) -> io::Result<bool>;
226199

227200
/// Returns whether the given terminal attribute is supported.
228-
fn supports_attr(&self, attr: attr::Attr) -> bool;
201+
fn supports_attr(&self, attr: Attr) -> bool;
229202

230-
/// Resets all terminal attributes and color to the default.
231-
/// Returns `Ok()`.
232-
fn reset(&mut self) -> io::Result<()>;
203+
/// Resets all terminal attributes and colors to their defaults.
204+
///
205+
/// Returns `Ok(true)` if the terminal was reset, `Ok(false)` otherwise, and `Err(e)` if there
206+
/// was an I/O error.
207+
///
208+
/// *Note: This does not flush.*
209+
///
210+
/// That means the reset command may get buffered so, if you aren't planning on doing anything
211+
/// else that might flush stdout's buffer (e.g. writing a line of text), you should flush after
212+
/// calling reset.
213+
fn reset(&mut self) -> io::Result<bool>;
233214

234215
/// Gets an immutable reference to the stream inside
235-
fn get_ref<'a>(&'a self) -> &'a T;
216+
fn get_ref<'a>(&'a self) -> &'a Self::Output;
236217

237218
/// Gets a mutable reference to the stream inside
238-
fn get_mut<'a>(&'a mut self) -> &'a mut T;
239-
}
219+
fn get_mut<'a>(&'a mut self) -> &'a mut Self::Output;
240220

241-
/// A terminal which can be unwrapped.
242-
pub trait UnwrappableTerminal<T: Write>: Terminal<T> {
243221
/// Returns the contained stream, destroying the `Terminal`
244-
fn unwrap(self) -> T;
222+
fn into_inner(self) -> Self::Output where Self: Sized;
245223
}

0 commit comments

Comments
 (0)