]>
Commit | Line | Data |
---|---|---|
92a42be0 | 1 | // Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT |
1a4d82fc JJ |
2 | // file at the top-level directory of this distribution and at |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
11 | //! Terminal formatting library. | |
12 | //! | |
13 | //! This crate provides the `Terminal` trait, which abstracts over an [ANSI | |
92a42be0 SL |
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 | |
1a4d82fc JJ |
17 | //! API][win]. |
18 | //! | |
19 | //! # Examples | |
20 | //! | |
21 | //! ```no_run | |
c34b1796 | 22 | //! # #![feature(rustc_private)] |
1a4d82fc | 23 | //! extern crate term; |
c34b1796 AL |
24 | //! use std::io::prelude::*; |
25 | //! | |
1a4d82fc JJ |
26 | //! fn main() { |
27 | //! let mut t = term::stdout().unwrap(); | |
28 | //! | |
29 | //! t.fg(term::color::GREEN).unwrap(); | |
92a42be0 | 30 | //! write!(t, "hello, ").unwrap(); |
1a4d82fc JJ |
31 | //! |
32 | //! t.fg(term::color::RED).unwrap(); | |
92a42be0 | 33 | //! writeln!(t, "world!").unwrap(); |
1a4d82fc | 34 | //! |
92a42be0 | 35 | //! assert!(t.reset().unwrap()); |
1a4d82fc JJ |
36 | //! } |
37 | //! ``` | |
38 | //! | |
39 | //! [ansi]: https://en.wikipedia.org/wiki/ANSI_escape_code | |
40 | //! [win]: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010%28v=vs.85%29.aspx | |
41 | //! [ti]: https://en.wikipedia.org/wiki/Terminfo | |
42 | ||
e9174d1e | 43 | #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", |
62682a34 | 44 | html_favicon_url = "https://doc.rust-lang.org/favicon.ico", |
e9174d1e | 45 | html_root_url = "https://doc.rust-lang.org/nightly/", |
92a42be0 SL |
46 | html_playground_url = "https://play.rust-lang.org/", |
47 | test(attr(deny(warnings))))] | |
85aaf69f | 48 | #![deny(missing_docs)] |
1a4d82fc | 49 | |
85aaf69f | 50 | #![cfg_attr(windows, feature(libc))] |
92a42be0 SL |
51 | // Handle rustfmt skips |
52 | #![feature(custom_attribute)] | |
53 | #![allow(unused_attributes)] | |
1a4d82fc | 54 | |
92a42be0 | 55 | use std::io::prelude::*; |
1a4d82fc JJ |
56 | |
57 | pub use terminfo::TerminfoTerminal; | |
58 | #[cfg(windows)] | |
59 | pub use win::WinConsole; | |
60 | ||
92a42be0 | 61 | use std::io::{self, Stdout, Stderr}; |
1a4d82fc JJ |
62 | |
63 | pub mod terminfo; | |
64 | ||
65 | #[cfg(windows)] | |
66 | mod win; | |
67 | ||
92a42be0 | 68 | /// Alias for stdout terminals. |
9cc50fc6 | 69 | pub type StdoutTerminal = Terminal<Output = Stdout> + Send; |
92a42be0 | 70 | /// Alias for stderr terminals. |
9cc50fc6 | 71 | pub type StderrTerminal = Terminal<Output = Stderr> + Send; |
1a4d82fc JJ |
72 | |
73 | #[cfg(not(windows))] | |
74 | /// Return a Terminal wrapping stdout, or None if a terminal couldn't be | |
75 | /// opened. | |
92a42be0 SL |
76 | pub fn stdout() -> Option<Box<StdoutTerminal>> { |
77 | TerminfoTerminal::new(io::stdout()).map(|t| Box::new(t) as Box<StdoutTerminal>) | |
1a4d82fc JJ |
78 | } |
79 | ||
80 | #[cfg(windows)] | |
81 | /// Return a Terminal wrapping stdout, or None if a terminal couldn't be | |
82 | /// opened. | |
92a42be0 SL |
83 | pub fn stdout() -> Option<Box<StdoutTerminal>> { |
84 | TerminfoTerminal::new(io::stdout()) | |
85 | .map(|t| Box::new(t) as Box<StdoutTerminal>) | |
86 | .or_else(|| WinConsole::new(io::stdout()).ok().map(|t| Box::new(t) as Box<StdoutTerminal>)) | |
1a4d82fc JJ |
87 | } |
88 | ||
89 | #[cfg(not(windows))] | |
90 | /// Return a Terminal wrapping stderr, or None if a terminal couldn't be | |
91 | /// opened. | |
92a42be0 SL |
92 | pub fn stderr() -> Option<Box<StderrTerminal>> { |
93 | TerminfoTerminal::new(io::stderr()).map(|t| Box::new(t) as Box<StderrTerminal>) | |
1a4d82fc JJ |
94 | } |
95 | ||
96 | #[cfg(windows)] | |
97 | /// Return a Terminal wrapping stderr, or None if a terminal couldn't be | |
98 | /// opened. | |
92a42be0 SL |
99 | pub fn stderr() -> Option<Box<StderrTerminal>> { |
100 | TerminfoTerminal::new(io::stderr()) | |
101 | .map(|t| Box::new(t) as Box<StderrTerminal>) | |
102 | .or_else(|| WinConsole::new(io::stderr()).ok().map(|t| Box::new(t) as Box<StderrTerminal>)) | |
1a4d82fc JJ |
103 | } |
104 | ||
105 | ||
106 | /// Terminal color definitions | |
c1a9b12d | 107 | #[allow(missing_docs)] |
1a4d82fc JJ |
108 | pub mod color { |
109 | /// Number for a terminal color | |
110 | pub type Color = u16; | |
111 | ||
92a42be0 SL |
112 | pub const BLACK: Color = 0; |
113 | pub const RED: Color = 1; | |
114 | pub const GREEN: Color = 2; | |
115 | pub const YELLOW: Color = 3; | |
116 | pub const BLUE: Color = 4; | |
c34b1796 | 117 | pub const MAGENTA: Color = 5; |
92a42be0 SL |
118 | pub const CYAN: Color = 6; |
119 | pub const WHITE: Color = 7; | |
120 | ||
121 | pub const BRIGHT_BLACK: Color = 8; | |
122 | pub const BRIGHT_RED: Color = 9; | |
123 | pub const BRIGHT_GREEN: Color = 10; | |
124 | pub const BRIGHT_YELLOW: Color = 11; | |
125 | pub const BRIGHT_BLUE: Color = 12; | |
c34b1796 | 126 | pub const BRIGHT_MAGENTA: Color = 13; |
92a42be0 SL |
127 | pub const BRIGHT_CYAN: Color = 14; |
128 | pub const BRIGHT_WHITE: Color = 15; | |
1a4d82fc JJ |
129 | } |
130 | ||
92a42be0 SL |
131 | /// Terminal attributes for use with term.attr(). |
132 | /// | |
133 | /// Most attributes can only be turned on and must be turned off with term.reset(). | |
134 | /// The ones that can be turned off explicitly take a boolean value. | |
135 | /// Color is also represented as an attribute for convenience. | |
136 | #[derive(Debug, PartialEq, Eq, Copy, Clone)] | |
137 | pub enum Attr { | |
138 | /// Bold (or possibly bright) mode | |
139 | Bold, | |
140 | /// Dim mode, also called faint or half-bright. Often not supported | |
141 | Dim, | |
142 | /// Italics mode. Often not supported | |
143 | Italic(bool), | |
144 | /// Underline mode | |
145 | Underline(bool), | |
146 | /// Blink mode | |
147 | Blink, | |
148 | /// Standout mode. Often implemented as Reverse, sometimes coupled with Bold | |
149 | Standout(bool), | |
150 | /// Reverse mode, inverts the foreground and background colors | |
151 | Reverse, | |
152 | /// Secure mode, also called invis mode. Hides the printed text | |
153 | Secure, | |
154 | /// Convenience attribute to set the foreground color | |
155 | ForegroundColor(color::Color), | |
156 | /// Convenience attribute to set the background color | |
157 | BackgroundColor(color::Color), | |
1a4d82fc JJ |
158 | } |
159 | ||
160 | /// A terminal with similar capabilities to an ANSI Terminal | |
161 | /// (foreground/background colors etc). | |
92a42be0 SL |
162 | pub trait Terminal: Write { |
163 | /// The terminal's output writer type. | |
164 | type Output: Write; | |
165 | ||
1a4d82fc JJ |
166 | /// Sets the foreground color to the given color. |
167 | /// | |
168 | /// If the color is a bright color, but the terminal only supports 8 colors, | |
169 | /// the corresponding normal color will be used instead. | |
170 | /// | |
171 | /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)` | |
172 | /// if there was an I/O error. | |
c34b1796 | 173 | fn fg(&mut self, color: color::Color) -> io::Result<bool>; |
1a4d82fc JJ |
174 | |
175 | /// Sets the background color to the given color. | |
176 | /// | |
177 | /// If the color is a bright color, but the terminal only supports 8 colors, | |
178 | /// the corresponding normal color will be used instead. | |
179 | /// | |
180 | /// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)` | |
181 | /// if there was an I/O error. | |
c34b1796 | 182 | fn bg(&mut self, color: color::Color) -> io::Result<bool>; |
1a4d82fc JJ |
183 | |
184 | /// Sets the given terminal attribute, if supported. Returns `Ok(true)` | |
185 | /// if the attribute was supported, `Ok(false)` otherwise, and `Err(e)` if | |
186 | /// there was an I/O error. | |
92a42be0 | 187 | fn attr(&mut self, attr: Attr) -> io::Result<bool>; |
1a4d82fc JJ |
188 | |
189 | /// Returns whether the given terminal attribute is supported. | |
92a42be0 | 190 | fn supports_attr(&self, attr: Attr) -> bool; |
1a4d82fc | 191 | |
92a42be0 SL |
192 | /// Resets all terminal attributes and colors to their defaults. |
193 | /// | |
194 | /// Returns `Ok(true)` if the terminal was reset, `Ok(false)` otherwise, and `Err(e)` if there | |
195 | /// was an I/O error. | |
196 | /// | |
197 | /// *Note: This does not flush.* | |
198 | /// | |
199 | /// That means the reset command may get buffered so, if you aren't planning on doing anything | |
200 | /// else that might flush stdout's buffer (e.g. writing a line of text), you should flush after | |
201 | /// calling reset. | |
202 | fn reset(&mut self) -> io::Result<bool>; | |
1a4d82fc JJ |
203 | |
204 | /// Gets an immutable reference to the stream inside | |
7453a54e | 205 | fn get_ref(&self) -> &Self::Output; |
1a4d82fc JJ |
206 | |
207 | /// Gets a mutable reference to the stream inside | |
7453a54e | 208 | fn get_mut(&mut self) -> &mut Self::Output; |
1a4d82fc | 209 | |
1a4d82fc | 210 | /// Returns the contained stream, destroying the `Terminal` |
92a42be0 | 211 | fn into_inner(self) -> Self::Output where Self: Sized; |
1a4d82fc | 212 | } |