1
- // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
1
+ // Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
2
2
// file at the top-level directory of this distribution and at
3
3
// http://rust-lang.org/COPYRIGHT.
4
4
//
11
11
//! Terminal formatting library.
12
12
//!
13
13
//! 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
17
17
//! API][win].
18
18
//!
19
19
//! # Examples
20
20
//!
21
21
//! ```no_run
22
22
//! # #![feature(rustc_private)]
23
23
//! extern crate term;
24
- //!
25
24
//! use std::io::prelude::*;
26
25
//!
27
26
//! fn main() {
28
27
//! let mut t = term::stdout().unwrap();
29
28
//!
30
29
//! t.fg(term::color::GREEN).unwrap();
31
- //! ( write!(t, "hello, ") ).unwrap();
30
+ //! write!(t, "hello, ").unwrap();
32
31
//!
33
32
//! t.fg(term::color::RED).unwrap();
34
- //! ( writeln!(t, "world!") ).unwrap();
33
+ //! writeln!(t, "world!").unwrap();
35
34
//!
36
- //! t.reset().unwrap();
35
+ //! assert!( t.reset().unwrap() );
37
36
//! }
38
37
//! ```
39
38
//!
58
57
#![ deny( missing_docs) ]
59
58
60
59
#![ feature( box_syntax) ]
61
- #![ feature( rustc_private) ]
62
60
#![ feature( staged_api) ]
63
- #![ feature( str_char) ]
64
- #![ feature( vec_push_all) ]
65
61
#![ cfg_attr( windows, feature( libc) ) ]
66
62
// Handle rustfmt skips
67
63
#![ feature( custom_attribute) ]
68
64
#![ allow( unused_attributes) ]
69
65
70
- #[ macro_use]
71
- extern crate log;
66
+ use std:: io:: prelude:: * ;
72
67
73
68
pub use terminfo:: TerminfoTerminal ;
74
69
#[ cfg( windows) ]
75
70
pub use win:: WinConsole ;
76
71
77
- use std:: io:: prelude:: * ;
78
- use std:: io;
72
+ use std:: io:: { self , Stdout , Stderr } ;
79
73
80
74
pub mod terminfo;
81
75
82
76
#[ cfg( windows) ]
83
77
mod win;
84
78
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 ;
102
83
103
84
#[ cfg( not( windows) ) ]
104
85
/// Return a Terminal wrapping stdout, or None if a terminal couldn't be
105
86
/// 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 > )
108
89
}
109
90
110
91
#[ cfg( windows) ]
111
92
/// Return a Terminal wrapping stdout, or None if a terminal couldn't be
112
93
/// 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 > ) )
120
98
}
121
99
122
100
#[ cfg( not( windows) ) ]
123
101
/// Return a Terminal wrapping stderr, or None if a terminal couldn't be
124
102
/// 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 > )
127
105
}
128
106
129
107
#[ cfg( windows) ]
130
108
/// Return a Terminal wrapping stderr, or None if a terminal couldn't be
131
109
/// 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 > ) )
139
114
}
140
115
141
116
@@ -164,43 +139,41 @@ pub mod color {
164
139
pub const BRIGHT_WHITE : Color = 15 ;
165
140
}
166
141
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 ) ,
199
169
}
200
170
201
171
/// A terminal with similar capabilities to an ANSI Terminal
202
172
/// (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
+
204
177
/// Sets the foreground color to the given color.
205
178
///
206
179
/// If the color is a bright color, but the terminal only supports 8 colors,
@@ -222,24 +195,29 @@ pub trait Terminal<T: Write>: Write {
222
195
/// Sets the given terminal attribute, if supported. Returns `Ok(true)`
223
196
/// if the attribute was supported, `Ok(false)` otherwise, and `Err(e)` if
224
197
/// 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 > ;
226
199
227
200
/// 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 ;
229
202
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 > ;
233
214
234
215
/// 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 ;
236
217
237
218
/// 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 ;
240
220
241
- /// A terminal which can be unwrapped.
242
- pub trait UnwrappableTerminal < T : Write > : Terminal < T > {
243
221
/// Returns the contained stream, destroying the `Terminal`
244
- fn unwrap ( self ) -> T ;
222
+ fn into_inner ( self ) -> Self :: Output where Self : Sized ;
245
223
}
0 commit comments