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//
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//!
5857#![ deny( missing_docs) ]
5958
6059#![ feature( box_syntax) ]
61- #![ feature( rustc_private) ]
6260#![ feature( staged_api) ]
6361#![ feature( str_char) ]
64- #![ feature( vec_push_all) ]
6562#![ cfg_attr( windows, feature( libc) ) ]
6663// Handle rustfmt skips
6764#![ feature( custom_attribute) ]
6865#![ allow( unused_attributes) ]
6966
70- #[ macro_use]
71- extern crate log;
67+ use std:: io:: prelude:: * ;
7268
7369pub use terminfo:: TerminfoTerminal ;
7470#[ cfg( windows) ]
7571pub use win:: WinConsole ;
7672
77- use std:: io:: prelude:: * ;
78- use std:: io;
73+ use std:: io:: { self , Stdout , Stderr } ;
7974
8075pub mod terminfo;
8176
8277#[ cfg( windows) ]
8378mod win;
8479
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- }
80+ /// Alias for stdout terminals.
81+ pub type StdoutTerminal = Terminal < Output =Stdout > + Send ;
82+ /// Alias for stderr terminals.
83+ pub type StderrTerminal = Terminal < Output =Stderr > + Send ;
10284
10385#[ cfg( not( windows) ) ]
10486/// Return a Terminal wrapping stdout, or None if a terminal couldn't be
10587/// opened.
106- pub fn stdout ( ) -> Option < Box < Terminal < WriterWrapper > + Send > > {
107- TerminfoTerminal :: new ( WriterWrapper { wrapped : box std :: io:: stdout ( ) } )
88+ pub fn stdout ( ) -> Option < Box < StdoutTerminal > > {
89+ TerminfoTerminal :: new ( io:: stdout ( ) ) . map ( |t| Box :: new ( t ) as Box < StdoutTerminal > )
10890}
10991
11092#[ cfg( windows) ]
11193/// Return a Terminal wrapping stdout, or None if a terminal couldn't be
11294/// 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- }
95+ pub fn stdout ( ) -> Option < Box < StdoutTerminal > > {
96+ TerminfoTerminal :: new ( io:: stdout ( ) )
97+ . map ( |t| Box :: new ( t) as Box < StdoutTerminal > )
98+ . or_else ( || WinConsole :: new ( io:: stdout ( ) ) . ok ( ) . map ( |t| Box :: new ( t) as Box < StdoutTerminal > ) )
12099}
121100
122101#[ cfg( not( windows) ) ]
123102/// Return a Terminal wrapping stderr, or None if a terminal couldn't be
124103/// opened.
125- pub fn stderr ( ) -> Option < Box < Terminal < WriterWrapper > + Send > > {
126- TerminfoTerminal :: new ( WriterWrapper { wrapped : box std :: io:: stderr ( ) } )
104+ pub fn stderr ( ) -> Option < Box < StderrTerminal > > {
105+ TerminfoTerminal :: new ( io:: stderr ( ) ) . map ( |t| Box :: new ( t ) as Box < StderrTerminal > )
127106}
128107
129108#[ cfg( windows) ]
130109/// Return a Terminal wrapping stderr, or None if a terminal couldn't be
131110/// 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- }
111+ pub fn stderr ( ) -> Option < Box < StderrTerminal > > {
112+ TerminfoTerminal :: new ( io:: stderr ( ) )
113+ . map ( |t| Box :: new ( t) as Box < StderrTerminal > )
114+ . or_else ( || WinConsole :: new ( io:: stderr ( ) ) . ok ( ) . map ( |t| Box :: new ( t) as Box < StderrTerminal > ) )
139115}
140116
141117
@@ -164,43 +140,41 @@ pub mod color {
164140 pub const BRIGHT_WHITE : Color = 15 ;
165141}
166142
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- }
143+ /// Terminal attributes for use with term.attr().
144+ ///
145+ /// Most attributes can only be turned on and must be turned off with term.reset().
146+ /// The ones that can be turned off explicitly take a boolean value.
147+ /// Color is also represented as an attribute for convenience.
148+ #[ derive( Debug , PartialEq , Eq , Copy , Clone ) ]
149+ pub enum Attr {
150+ /// Bold (or possibly bright) mode
151+ Bold ,
152+ /// Dim mode, also called faint or half-bright. Often not supported
153+ Dim ,
154+ /// Italics mode. Often not supported
155+ Italic ( bool ) ,
156+ /// Underline mode
157+ Underline ( bool ) ,
158+ /// Blink mode
159+ Blink ,
160+ /// Standout mode. Often implemented as Reverse, sometimes coupled with Bold
161+ Standout ( bool ) ,
162+ /// Reverse mode, inverts the foreground and background colors
163+ Reverse ,
164+ /// Secure mode, also called invis mode. Hides the printed text
165+ Secure ,
166+ /// Convenience attribute to set the foreground color
167+ ForegroundColor ( color:: Color ) ,
168+ /// Convenience attribute to set the background color
169+ BackgroundColor ( color:: Color ) ,
199170}
200171
201172/// A terminal with similar capabilities to an ANSI Terminal
202173/// (foreground/background colors etc).
203- pub trait Terminal < T : Write > : Write {
174+ pub trait Terminal : Write {
175+ /// The terminal's output writer type.
176+ type Output : Write ;
177+
204178 /// Sets the foreground color to the given color.
205179 ///
206180 /// If the color is a bright color, but the terminal only supports 8 colors,
@@ -222,24 +196,29 @@ pub trait Terminal<T: Write>: Write {
222196 /// Sets the given terminal attribute, if supported. Returns `Ok(true)`
223197 /// if the attribute was supported, `Ok(false)` otherwise, and `Err(e)` if
224198 /// there was an I/O error.
225- fn attr ( & mut self , attr : attr :: Attr ) -> io:: Result < bool > ;
199+ fn attr ( & mut self , attr : Attr ) -> io:: Result < bool > ;
226200
227201 /// Returns whether the given terminal attribute is supported.
228- fn supports_attr ( & self , attr : attr :: Attr ) -> bool ;
202+ fn supports_attr ( & self , attr : Attr ) -> bool ;
229203
230- /// Resets all terminal attributes and color to the default.
231- /// Returns `Ok()`.
232- fn reset ( & mut self ) -> io:: Result < ( ) > ;
204+ /// Resets all terminal attributes and colors to their defaults.
205+ ///
206+ /// Returns `Ok(true)` if the terminal was reset, `Ok(false)` otherwise, and `Err(e)` if there
207+ /// was an I/O error.
208+ ///
209+ /// *Note: This does not flush.*
210+ ///
211+ /// That means the reset command may get buffered so, if you aren't planning on doing anything
212+ /// else that might flush stdout's buffer (e.g. writing a line of text), you should flush after
213+ /// calling reset.
214+ fn reset ( & mut self ) -> io:: Result < bool > ;
233215
234216 /// Gets an immutable reference to the stream inside
235- fn get_ref < ' a > ( & ' a self ) -> & ' a T ;
217+ fn get_ref < ' a > ( & ' a self ) -> & ' a Self :: Output ;
236218
237219 /// Gets a mutable reference to the stream inside
238- fn get_mut < ' a > ( & ' a mut self ) -> & ' a mut T ;
239- }
220+ fn get_mut < ' a > ( & ' a mut self ) -> & ' a mut Self :: Output ;
240221
241- /// A terminal which can be unwrapped.
242- pub trait UnwrappableTerminal < T : Write > : Terminal < T > {
243222 /// Returns the contained stream, destroying the `Terminal`
244- fn unwrap ( self ) -> T ;
223+ fn into_inner ( self ) -> Self :: Output where Self : Sized ;
245224}
0 commit comments