use std::collections::HashMap;
use serialize::{Encodable,Encoder};
use toml;
-use util::{CargoResult, Require, error, internal_error};
+use util::{CargoResult, ChainError, Require, error, internal_error};
pub struct Config {
home_path: Path
impl Config {
pub fn new() -> CargoResult<Config> {
Ok(Config {
- home_path: try!(os::homedir()
+ home_path: cargo_try!(os::homedir()
.require(|| "Couldn't find the home directory"))
})
}
pub fn all_configs(pwd: Path) -> CargoResult<HashMap<String, ConfigValue>> {
let mut map = HashMap::new();
- try!(walk_tree(&pwd, |file| {
+ cargo_try!(walk_tree(&pwd, |file| {
extract_all_configs(file, &mut map)
}));
loop {
let possible = current.join(".cargo").join("config");
if possible.exists() {
- let file = try!(io::fs::File::open(&possible).map_err(|_| error("could not open file")));
+ let file = cargo_try!(io::fs::File::open(&possible).chain_error(|| error("could not open file")));
match walk(file) {
Ok(res) => return Ok(res),
_ => ()
loop {
let possible = current.join(".cargo").join("config");
if possible.exists() {
- let file = try!(io::fs::File::open(&possible).map_err(|_| error("could not open file")));
+ let file = cargo_try!(io::fs::File::open(&possible).chain_error(|| error("could not open file")));
match walk(file) {
Err(_) => err = false,
_ => ()
fn extract_config(file: io::fs::File, key: &str) -> CargoResult<ConfigValue> {
let path = file.path().clone();
let mut buf = io::BufferedReader::new(file);
- let root = try!(toml::parse_from_buffer(&mut buf).map_err(|_| error("")));
- let val = try!(root.lookup(key).require(|| error("")));
+ let root = cargo_try!(toml::parse_from_buffer(&mut buf));
+ let val = cargo_try!(root.lookup(key).require(|| error("")));
let v = match val {
&toml::String(ref val) => String(val.clone()),
fn extract_all_configs(file: io::fs::File, map: &mut HashMap<String, ConfigValue>) -> CargoResult<()> {
let path = file.path().clone();
let mut buf = io::BufferedReader::new(file);
- let root = try!(toml::parse_from_buffer(&mut buf).map_err(|err|
- internal_error("could not parse Toml manifest", format!("path={}; err={}", path.display(), err.to_str()))));
+ let root = cargo_try!(toml::parse_from_buffer(&mut buf).chain_error(||
+ error(format!("could not parse Toml manifest; path={}", path.display()))));
- let table = try!(root.get_table()
- .require(|| internal_error("could not parse Toml manifest", format!("path={}", path.display()))));
+ let table = cargo_try!(root.get_table().require(||
+ error(format!("could not parse Toml manifest; path={}", path.display()))));
for (key, value) in table.iter() {
match value {
ConfigValue { path: vec!(), value: List(vec!()) }
});
- try!(merge_array(config, val.as_slice(), &path).map_err(|err|
- error(format!("The `{}` key in your config {}", key, err))));
+ cargo_try!(merge_array(config, val.as_slice(), &path).chain_error(||
+ error(format!("The `{}` key in your config", key))));
},
_ => ()
}
fn cause<'a>(&'a self) -> Option<&'a CargoError> { None }
fn is_human(&self) -> bool { false }
+ fn to_error<E: FromError<Self>>(self) -> E {
+ FromError::from_error(self)
+ }
+
fn box_error(self) -> Box<CargoError> {
box self as Box<CargoError>
}
}
}
+pub trait FromError<E> {
+ fn from_error(error: E) -> Self;
+}
+
+impl<E: CargoError> FromError<E> for Box<CargoError> {
+ fn from_error(error: E) -> Box<CargoError> {
+ error.box_error()
+ }
+}
+
+macro_rules! from_error (
+ ($ty:ty) => {
+ impl FromError<$ty> for $ty {
+ fn from_error(error: $ty) -> $ty {
+ error
+ }
+ }
+ }
+)
impl Show for Box<CargoError> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
fn description(&self) -> String { self.to_str() }
}
+from_error!(IoError)
+
impl CargoError for TomlError {
fn description(&self) -> String { self.to_str() }
}
+from_error!(TomlError)
+
pub struct ProcessError {
pub msg: String,
pub command: String,
pub cause: Option<Box<CargoError>>
}
+from_error!(ProcessError)
+
impl Show for ProcessError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
let exit = match self.exit {