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
61
#![ feature( str_char) ]
64
- #![ feature( vec_push_all) ]
65
62
#![ cfg_attr( windows, feature( libc) ) ]
66
63
// Handle rustfmt skips
67
64
#![ feature( custom_attribute) ]
68
65
#![ allow( unused_attributes) ]
69
66
70
- #[ macro_use]
71
- extern crate log;
67
+ use std:: io:: prelude:: * ;
72
68
73
69
pub use terminfo:: TerminfoTerminal ;
74
70
#[ cfg( windows) ]
75
71
pub use win:: WinConsole ;
76
72
77
- use std:: io:: prelude:: * ;
78
- use std:: io;
73
+ use std:: io:: { self , Stdout , Stderr } ;
79
74
80
75
pub mod terminfo;
81
76
82
77
#[ cfg( windows) ]
83
78
mod win;
84
79
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 ;
102
84
103
85
#[ cfg( not( windows) ) ]
104
86
/// Return a Terminal wrapping stdout, or None if a terminal couldn't be
105
87
/// 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 > )
108
90
}
109
91
110
92
#[ cfg( windows) ]
111
93
/// Return a Terminal wrapping stdout, or None if a terminal couldn't be
112
94
/// 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 > ) )
120
99
}
121
100
122
101
#[ cfg( not( windows) ) ]
123
102
/// Return a Terminal wrapping stderr, or None if a terminal couldn't be
124
103
/// 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 > )
127
106
}
128
107
129
108
#[ cfg( windows) ]
130
109
/// Return a Terminal wrapping stderr, or None if a terminal couldn't be
131
110
/// 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 > ) )
139
115
}
140
116
141
117
@@ -164,43 +140,41 @@ pub mod color {
164
140
pub const BRIGHT_WHITE : Color = 15 ;
165
141
}
166
142
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 ) ,
199
170
}
200
171
201
172
/// A terminal with similar capabilities to an ANSI Terminal
202
173
/// (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
+
204
178
/// Sets the foreground color to the given color.
205
179
///
206
180
/// If the color is a bright color, but the terminal only supports 8 colors,
@@ -222,24 +196,29 @@ pub trait Terminal<T: Write>: Write {
222
196
/// Sets the given terminal attribute, if supported. Returns `Ok(true)`
223
197
/// if the attribute was supported, `Ok(false)` otherwise, and `Err(e)` if
224
198
/// 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 > ;
226
200
227
201
/// 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 ;
229
203
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 > ;
233
215
234
216
/// 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 ;
236
218
237
219
/// 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 ;
240
221
241
- /// A terminal which can be unwrapped.
242
- pub trait UnwrappableTerminal < T : Write > : Terminal < T > {
243
222
/// Returns the contained stream, destroying the `Terminal`
244
- fn unwrap ( self ) -> T ;
223
+ fn into_inner ( self ) -> Self :: Output where Self : Sized ;
245
224
}
0 commit comments