Start adding a shell abstraction

This commit is contained in:
Yehuda Katz 2014-05-27 16:47:04 -07:00
parent 7e6433feda
commit 93558906d8
3 changed files with 182 additions and 1 deletions

View file

@ -36,5 +36,6 @@ pub mod dependency;
pub mod manifest; pub mod manifest;
pub mod resolver; pub mod resolver;
pub mod summary; pub mod summary;
pub mod shell;
mod registry; mod registry;
mod version_req; mod version_req;

179
src/cargo/core/shell.rs Normal file
View file

@ -0,0 +1,179 @@
use term;
use term::{Terminal,color};
use term::color::Color;
use term::attr::Attr;
use std::io::IoResult;
use std::io::stdio::StdWriter;
pub struct ShellConfig {
color: bool,
verbose: bool
}
enum AdequateTerminal {
NoColor(BasicTerminal<StdWriter>),
Color(Box<Terminal<StdWriter>>)
}
pub struct Shell {
terminal: AdequateTerminal,
config: ShellConfig
}
impl Shell {
fn create(out: StdWriter, config: ShellConfig) -> Option<Shell> {
let term = if out.isatty() {
let term: Option<term::TerminfoTerminal<StdWriter>> = Terminal::new(out);
term.map(|t| Color(box t))
} else {
Some(NoColor(BasicTerminal { writer: out }))
};
term.map(|term| Shell { terminal: term, config: config })
}
pub fn verbose(&mut self, callback: |&mut Shell| -> IoResult<()>) -> IoResult<()> {
if self.config.verbose {
return callback(self)
}
Ok(())
}
pub fn say<T: Str>(&mut self, message: T, color: Color) -> IoResult<()> {
try!(self.reset());
try!(self.fg(color));
try!(self.write_line(message.as_slice()));
try!(self.reset());
try!(self.flush());
Ok(())
}
}
impl Terminal<StdWriter> for Shell {
fn new(out: StdWriter) -> Option<Shell> {
Shell::create(out, ShellConfig { color: true, verbose: false })
}
fn fg(&mut self, color: color::Color) -> IoResult<bool> {
match self.terminal {
Color(ref mut c) => c.fg(color),
NoColor(ref mut n) => n.fg(color)
}
}
fn bg(&mut self, color: color::Color) -> IoResult<bool> {
match self.terminal {
Color(ref mut c) => c.bg(color),
NoColor(ref mut n) => n.bg(color)
}
}
fn attr(&mut self, attr: Attr) -> IoResult<bool> {
match self.terminal {
Color(ref mut c) => c.attr(attr),
NoColor(ref mut n) => n.attr(attr)
}
}
fn supports_attr(&self, attr: Attr) -> bool {
match self.terminal {
Color(ref c) => c.supports_attr(attr),
NoColor(ref n) => n.supports_attr(attr)
}
}
fn reset(&mut self) -> IoResult<()> {
match self.terminal {
Color(ref mut c) => c.reset(),
NoColor(ref mut n) => n.reset()
}
}
fn unwrap(self) -> StdWriter {
fail!("Can't unwrap a Shell")
}
fn get_ref<'a>(&'a self) -> &'a StdWriter {
match self.terminal {
Color(ref c) => c.get_ref(),
NoColor(ref n) => n.get_ref()
}
}
fn get_mut<'a>(&'a mut self) -> &'a mut StdWriter {
match self.terminal {
Color(ref mut c) => c.get_mut(),
NoColor(ref mut n) => n.get_mut()
}
}
}
impl Writer for Shell {
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
match self.terminal {
Color(ref mut c) => c.write(buf),
NoColor(ref mut n) => n.write(buf)
}
}
fn flush(&mut self) -> IoResult<()> {
match self.terminal {
Color(ref mut c) => c.flush(),
NoColor(ref mut n) => n.flush()
}
}
}
pub struct BasicTerminal<T> {
writer: T
}
impl<T: Writer> Terminal<T> for BasicTerminal<T> {
fn new(out: T) -> Option<BasicTerminal<T>> {
Some(BasicTerminal { writer: out })
}
fn fg(&mut self, _: Color) -> IoResult<bool> {
Ok(false)
}
fn bg(&mut self, _: Color) -> IoResult<bool> {
Ok(false)
}
fn attr(&mut self, _: Attr) -> IoResult<bool> {
Ok(false)
}
fn supports_attr(&self, _: Attr) -> bool {
false
}
fn reset(&mut self) -> IoResult<()> {
Ok(())
}
fn unwrap(self) -> T {
self.writer
}
fn get_ref<'a>(&'a self) -> &'a T {
&self.writer
}
fn get_mut<'a>(&'a mut self) -> &'a mut T {
&mut self.writer
}
}
impl<T: Writer> Writer for BasicTerminal<T> {
fn write(&mut self, buf: &[u8]) -> IoResult<()> {
self.writer.write(buf)
}
fn flush(&mut self) -> IoResult<()> {
self.writer.flush()
}
}

View file

@ -5,10 +5,11 @@
#![feature(macro_rules,phase)] #![feature(macro_rules,phase)]
extern crate collections; extern crate collections;
extern crate term;
extern crate url; extern crate url;
extern crate hammer;
extern crate serialize; extern crate serialize;
extern crate semver; extern crate semver;
extern crate hammer;
extern crate toml; extern crate toml;
#[phase(syntax, link)] #[phase(syntax, link)]