summary refs log tree commit diff
path: root/src/libterm
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2014-10-01 19:01:08 +1300
committerNick Cameron <ncameron@mozilla.com>2014-10-30 15:51:55 +1300
commit1d500cfd74c02b6f9f84a4e7387d8126c79f3f76 (patch)
treef4c5489c98cfb2deb492c37021f4ab7d3ed54427 /src/libterm
parent8d8d8d4e5292c2fa4a622d981a5f85fd3d8f34d0 (diff)
downloadrust-1d500cfd74c02b6f9f84a4e7387d8126c79f3f76.tar.gz
rust-1d500cfd74c02b6f9f84a4e7387d8126c79f3f76.zip
changes to libs
Diffstat (limited to 'src/libterm')
-rw-r--r--src/libterm/lib.rs29
-rw-r--r--src/libterm/terminfo/mod.rs91
2 files changed, 62 insertions, 58 deletions
diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs
index fbf17b76d62..37c7162333b 100644
--- a/src/libterm/lib.rs
+++ b/src/libterm/lib.rs
@@ -89,11 +89,9 @@ impl Writer for WriterWrapper {
 /// Return a Terminal wrapping stdout, or None if a terminal couldn't be
 /// opened.
 pub fn stdout() -> Option<Box<Terminal<WriterWrapper> + Send>> {
-    let ti: Option<TerminfoTerminal<WriterWrapper>>
-        = Terminal::new(WriterWrapper {
-            wrapped: box std::io::stdout() as Box<Writer + Send>,
-        });
-    ti.map(|t| box t as Box<Terminal<WriterWrapper> + Send>)
+    TerminfoTerminal::new(WriterWrapper {
+        wrapped: box std::io::stdout() as Box<Writer + Send>,
+    })
 }
 
 #[cfg(windows)]
@@ -121,11 +119,9 @@ pub fn stdout() -> Option<Box<Terminal<WriterWrapper> + Send>> {
 /// Return a Terminal wrapping stderr, or None if a terminal couldn't be
 /// opened.
 pub fn stderr() -> Option<Box<Terminal<WriterWrapper> + Send> + Send> {
-    let ti: Option<TerminfoTerminal<WriterWrapper>>
-        = Terminal::new(WriterWrapper {
-            wrapped: box std::io::stderr() as Box<Writer + Send>,
-        });
-    ti.map(|t| box t as Box<Terminal<WriterWrapper> + Send>)
+    TerminfoTerminal::new(WriterWrapper {
+        wrapped: box std::io::stderr() as Box<Writer + Send>,
+    })
 }
 
 #[cfg(windows)]
@@ -208,10 +204,6 @@ pub mod attr {
 /// A terminal with similar capabilities to an ANSI Terminal
 /// (foreground/background colors etc).
 pub trait Terminal<T: Writer>: Writer {
-    /// Returns `None` whenever the terminal cannot be created for some
-    /// reason.
-    fn new(out: T) -> Option<Self>;
-
     /// Sets the foreground color to the given color.
     ///
     /// If the color is a bright color, but the terminal only supports 8 colors,
@@ -242,12 +234,15 @@ pub trait Terminal<T: Writer>: Writer {
     /// Returns `Ok()`.
     fn reset(&mut self) -> IoResult<()>;
 
-    /// Returns the contained stream, destroying the `Terminal`
-    fn unwrap(self) -> T;
-
     /// Gets an immutable reference to the stream inside
     fn get_ref<'a>(&'a self) -> &'a T;
 
     /// Gets a mutable reference to the stream inside
     fn get_mut<'a>(&'a mut self) -> &'a mut T;
 }
+
+/// A terminal which can be unwrapped.
+pub trait UnwrappableTerminal<T: Writer>: Terminal<T> {
+    /// Returns the contained stream, destroying the `Terminal`
+    fn unwrap(self) -> T;
+}
diff --git a/src/libterm/terminfo/mod.rs b/src/libterm/terminfo/mod.rs
index 36883c8fcf4..73edcf94892 100644
--- a/src/libterm/terminfo/mod.rs
+++ b/src/libterm/terminfo/mod.rs
@@ -17,6 +17,7 @@ use std::os;
 use attr;
 use color;
 use Terminal;
+use UnwrappableTerminal;
 use self::searcher::open;
 use self::parser::compiled::{parse, msys_terminfo};
 use self::parm::{expand, Number, Variables};
@@ -71,44 +72,7 @@ pub struct TerminfoTerminal<T> {
     ti: Box<TermInfo>
 }
 
-impl<T: Writer> Terminal<T> for TerminfoTerminal<T> {
-    fn new(out: T) -> Option<TerminfoTerminal<T>> {
-        let term = match os::getenv("TERM") {
-            Some(t) => t,
-            None => {
-                debug!("TERM environment variable not defined");
-                return None;
-            }
-        };
-
-        let entry = open(term.as_slice());
-        if entry.is_err() {
-            if os::getenv("MSYSCON").map_or(false, |s| {
-                    "mintty.exe" == s.as_slice()
-                }) {
-                // msys terminal
-                return Some(TerminfoTerminal {out: out, ti: msys_terminfo(), num_colors: 8});
-            }
-            debug!("error finding terminfo entry: {}", entry.err().unwrap());
-            return None;
-        }
-
-        let mut file = entry.unwrap();
-        let ti = parse(&mut file, false);
-        if ti.is_err() {
-            debug!("error parsing terminfo entry: {}", ti.unwrap_err());
-            return None;
-        }
-
-        let inf = ti.unwrap();
-        let nc = if inf.strings.find_equiv(&("setaf")).is_some()
-                 && inf.strings.find_equiv(&("setab")).is_some() {
-                     inf.numbers.find_equiv(&("colors")).map_or(0, |&n| n)
-                 } else { 0 };
-
-        return Some(TerminfoTerminal {out: out, ti: inf, num_colors: nc});
-    }
-
+impl<T: Writer+Send> Terminal<T> for TerminfoTerminal<T> {
     fn fg(&mut self, color: color::Color) -> IoResult<bool> {
         let color = self.dim_if_necessary(color);
         if self.num_colors > color {
@@ -195,14 +159,59 @@ impl<T: Writer> Terminal<T> for TerminfoTerminal<T> {
         Ok(())
     }
 
-    fn unwrap(self) -> T { self.out }
-
     fn get_ref<'a>(&'a self) -> &'a T { &self.out }
 
     fn get_mut<'a>(&'a mut self) -> &'a mut T { &mut self.out }
 }
 
-impl<T: Writer> TerminfoTerminal<T> {
+impl<T: Writer+Send> UnwrappableTerminal<T> for TerminfoTerminal<T> {
+    fn unwrap(self) -> T { self.out }
+}
+
+impl<T: Writer+Send> TerminfoTerminal<T> {
+    /// Returns `None` whenever the terminal cannot be created for some
+    /// reason.
+    pub fn new(out: T) -> Option<Box<Terminal<T>+Send+'static>> {
+        let term = match os::getenv("TERM") {
+            Some(t) => t,
+            None => {
+                debug!("TERM environment variable not defined");
+                return None;
+            }
+        };
+
+        let entry = open(term.as_slice());
+        if entry.is_err() {
+            if os::getenv("MSYSCON").map_or(false, |s| {
+                    "mintty.exe" == s.as_slice()
+                }) {
+                // msys terminal
+                return Some(box TerminfoTerminal {out: out,
+                                                  ti: msys_terminfo(),
+                                                  num_colors: 8} as Box<Terminal<T>+Send>);
+            }
+            debug!("error finding terminfo entry: {}", entry.err().unwrap());
+            return None;
+        }
+
+        let mut file = entry.unwrap();
+        let ti = parse(&mut file, false);
+        if ti.is_err() {
+            debug!("error parsing terminfo entry: {}", ti.unwrap_err());
+            return None;
+        }
+
+        let inf = ti.unwrap();
+        let nc = if inf.strings.find_equiv(&("setaf")).is_some()
+                 && inf.strings.find_equiv(&("setab")).is_some() {
+                     inf.numbers.find_equiv(&("colors")).map_or(0, |&n| n)
+                 } else { 0 };
+
+        return Some(box TerminfoTerminal {out: out,
+                                          ti: inf,
+                                          num_colors: nc} as Box<Terminal<T>+Send>);
+    }
+
     fn dim_if_necessary(&self, color: color::Color) -> color::Color {
         if color >= self.num_colors && color >= 8 && color < 16 {
             color-8