From 4e2937fc614538fd73363a41667c9472fb6ff5f3 Mon Sep 17 00:00:00 2001 From: bnewbold Date: Tue, 27 Dec 2016 20:58:51 +0100 Subject: refactor error handling with error_chain --- Cargo.lock | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/bin/mt-tool.rs | 36 ++++++++++++++++++++++++------- src/bin/mt-webface.rs | 5 +++++ src/lib.rs | 19 ++++++++++++++--- src/modelica_model.rs | 47 ++++++++++++++++++++-------------------- src/transpile_js.rs | 12 +++++------ src/transpile_scheme.rs | 12 +++++------ 8 files changed, 142 insertions(+), 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d293506..f631263 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,6 +5,7 @@ dependencies = [ "clap 2.19.2 (registry+https://github.com/rust-lang/crates.io-index)", "docopt 0.6.86 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "error-chain 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "markdown 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -37,6 +38,29 @@ dependencies = [ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "backtrace" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "backtrace-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "bit-set" version = "0.3.0" @@ -65,6 +89,11 @@ name = "buf-read-ext" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "cfg-if" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "clap" version = "2.19.2" @@ -99,6 +128,15 @@ dependencies = [ "url 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "dbghelp-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "diff" version = "0.1.9" @@ -189,6 +227,14 @@ dependencies = [ "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "error-chain" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fixedbitset" version = "0.1.5" @@ -620,6 +666,11 @@ name = "regex-syntax" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rustc-demangle" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "rustc-serialize" version = "0.3.21" @@ -833,14 +884,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66" "checksum ansi_term 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23ac7c30002a5accbf7e8987d0632fa6de155b7c3d39d0067317a391e00a2ef6" "checksum atty 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d0fd4c0631f06448cc45a6bbb3b710ebb7ff8ccb96a0800c994afe23a70d5df2" +"checksum backtrace 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f551bc2ddd53aea015d453ef0b635af89444afa5ed2405dd0b2062ad5d600d80" +"checksum backtrace-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3602e8d8c43336088a8505fa55cae2b3884a9be29440863a11528a42f46f6bb7" "checksum bit-set 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "84527c7b0452f22545cc010e72d366a435561d2b28b978035550b3778c4d428d" "checksum bit-vec 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5b97c2c8e8bbb4251754f559df8af22fb264853c7d009084a576cdf12565089d" "checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3" "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" "checksum buf-read-ext 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cc384072fac32fb50f4a327c33e2004897d11c561d008dd6031fb7f19b04de2c" +"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c" "checksum clap 2.19.2 (registry+https://github.com/rust-lang/crates.io-index)" = "305ad043f009db535a110200541d4567b63e172b1fe030313fbb92565da7ed24" "checksum colored 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "585756a5d597a0ecdf9c963be84c6eb0e25a3590b535ac6f27e98254266b4f4c" "checksum cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0e3d6405328b6edb412158b3b7710e2634e23f3614b9bb1c412df7952489a626" +"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" "checksum diff 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e48977eec6d3b7707462c2dc2e1363ad91b5dd822cf942537ccdc2085dc87587" "checksum difference 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ffef4c144e881a906ed5bd6e1e749dc1955cd3f0c7969d3d34122a971981c5ea" "checksum docopt 0.6.86 (registry+https://github.com/rust-lang/crates.io-index)" = "4a7ef30445607f6fc8720f0a0a2c7442284b629cf0d049286860fae23e71c4d9" @@ -852,6 +907,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" "checksum encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" "checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f" +"checksum error-chain 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "318cb3c71ee4cdea69fdc9e15c173b245ed6063e1709029e8fd32525a881120f" "checksum fixedbitset 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "88c3c33fc4c00db33f5174eb98aea809c4c007db0b71351d810a7e094ea3b64d" "checksum formdata 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdb413b0e4962de166e7904607bb0f6070bc4d0cdc90a50bd6ce2d2d23e59a19" "checksum gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)" = "553f11439bdefe755bf366b264820f1da70f3aaf3924e594b886beb9c831bcf5" @@ -900,6 +956,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f" "checksum regex-syntax 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a21935ce5a4dfa48e3ded1aefbbe353fb9ab258b0d3fa0bd168bef00797b3dc7" "checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957" +"checksum rustc-demangle 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1430d286cadb237c17c885e25447c982c97113926bb579f4379c0eca8d9586dc" "checksum rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)" = "bff9fc1c79f2dec76b253273d07682e94a978bd8f132ded071188122b2af9818" "checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" "checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" diff --git a/Cargo.toml b/Cargo.toml index 18d91c6..663c8b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ toml = "0.2" log = "0.3" env_logger = "0.3" markdown = "0.1" +error-chain = "0.7" modelica-parser-lalrpop = { version = "*", path = "./modelica-parser-lalrpop" } # parser util diff --git a/src/bin/mt-tool.rs b/src/bin/mt-tool.rs index c04d5ab..e554636 100644 --- a/src/bin/mt-tool.rs +++ b/src/bin/mt-tool.rs @@ -7,6 +7,7 @@ extern crate modelica_parser; use modelthing::transpile_scheme::TranspileScheme; use modelthing::transpile_js::TranspileJS; use modelthing::modelica_model::ModelicaModelExt; +use modelthing::Result; use clap::{App, SubCommand}; use std::io::Read; use std::fs::File; @@ -35,7 +36,7 @@ fn parse_modelica_files(paths: Vec) { } } -fn main() { +fn run() -> Result<()> { let matches = App::new("mt-tool") .version(env!("CARGO_PKG_VERSION")) @@ -69,18 +70,18 @@ fn main() { let dir = Path::new(subm.value_of("DIR").unwrap()); let indep = subm.values_of_lossy("indep").unwrap(); let dep = subm.values_of_lossy("dep").unwrap(); - let me = modelthing::load_model_entry(dir).unwrap(); - println!("{:?}", me.ast.solve_for(indep, dep)); + let me = try!(modelthing::load_model_entry(dir)); + println!("{:?}", try!(me.ast.solve_for(indep, dep))); }, ("transpile_scheme", Some(subm)) => { let dir = Path::new(subm.value_of("DIR").unwrap()); - let me = modelthing::load_model_entry(dir).unwrap(); - println!("{}", me.ast.repr_scheme().unwrap()); + let me = try!(modelthing::load_model_entry(dir)); + println!("{}", try!(me.ast.repr_scheme())); }, ("transpile_js", Some(subm)) => { let dir = Path::new(subm.value_of("DIR").unwrap()); - let me = modelthing::load_model_entry(dir).unwrap(); - println!("{}", me.ast.repr_js().unwrap()); + let me = try!(modelthing::load_model_entry(dir)); + println!("{}", try!(me.ast.repr_js())); }, ("list", Some(subm)) => { let dir = Path::new(subm.value_of("DIR").unwrap_or("examples")); @@ -90,7 +91,7 @@ fn main() { }, ("load", Some(subm)) => { let dir = Path::new(subm.value_of("DIR").unwrap()); - let me = modelthing::load_model_entry(dir).unwrap(); + let me = try!(modelthing::load_model_entry(dir)); println!("{:?}", me); }, _ => { @@ -99,4 +100,23 @@ fn main() { ::std::process::exit(-1); }, } + Ok(()) +} + +fn main() { + if let Err(ref e) = run() { + println!("error: {}", e); + + for e in e.iter().skip(1) { + println!("caused by: {}", e); + } + + // The backtrace is not always generated. Try to run this example + // with `RUST_BACKTRACE=1`. + if let Some(backtrace) = e.backtrace() { + println!("backtrace: {:?}", backtrace); + } + + ::std::process::exit(1); + } } diff --git a/src/bin/mt-webface.rs b/src/bin/mt-webface.rs index b35deec..4cdc509 100644 --- a/src/bin/mt-webface.rs +++ b/src/bin/mt-webface.rs @@ -15,6 +15,11 @@ use getopts::Options; use pencil::Pencil; use pencil::{Request, PencilResult, Response, HTTPError, PencilError}; +/* +This command doesn't use error_chain (or raise errors in general) because the +web framework handles panics as 500 errors automatically. +*/ + fn home(r: &mut Request) -> PencilResult { let context: BTreeMap = BTreeMap::new(); diff --git a/src/lib.rs b/src/lib.rs index f93f7fa..24b1ee7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,9 @@ #[macro_use] extern crate log; +#[macro_use] +extern crate error_chain; + extern crate toml; extern crate modelica_parser; @@ -14,6 +17,12 @@ use std::fs; use std::io::Read; use std::fs::File; +mod errors { + // Create the Error, ErrorKind, ResultExt, and Result types + error_chain! { } +} +pub use errors::*; + #[derive(Debug, PartialEq)] pub enum ModelVarType { Independent, @@ -39,7 +48,7 @@ pub struct ModelEntry { pub markdown: String, } -pub fn load_model_entry(p: &Path) -> Result { +pub fn load_model_entry(p: &Path) -> Result { debug!("Attempting to load model from: {:?}", p); let ast = { @@ -65,9 +74,13 @@ pub fn load_model_entry(p: &Path) -> Result { } pub fn search_models(p: &Path) -> Vec { - if fs::metadata(p).unwrap().is_dir() { + let metadata = match fs::metadata(p) { + Err(_) => return vec![], + Ok(m) => m, + }; + if metadata.is_dir() { fs::read_dir(p) - .unwrap() + .unwrap() // exists and is_dir(); could be a race condition though? .map(|x| x.unwrap()) .filter(|x| x.metadata().unwrap().is_dir()) .filter(|x| x.path().join("model.modelica").exists()) diff --git a/src/modelica_model.rs b/src/modelica_model.rs index 785b8ae..40b83d6 100644 --- a/src/modelica_model.rs +++ b/src/modelica_model.rs @@ -7,9 +7,10 @@ use std::collections::HashSet; use std::iter::FromIterator; use self::modelica_parser::*; +use errors::Result; -/// / Helpers +/// Helpers pub trait ModelicaModelExt { fn get_constant_vars(&self) -> HashMap>; @@ -17,7 +18,7 @@ pub trait ModelicaModelExt { fn solve_for(&self, indep_vars: Vec, dep_vars: Vec) - -> Result; + -> Result; } impl ModelicaModelExt for ModelicaModel { @@ -74,7 +75,7 @@ impl ModelicaModelExt for ModelicaModel { fn solve_for(&self, indep_vars: Vec, dep_vars: Vec) - -> Result { + -> Result { let indep_vars: HashSet = HashSet::from_iter(indep_vars); let dep_vars: HashSet = HashSet::from_iter(dep_vars); @@ -89,27 +90,27 @@ impl ModelicaModelExt for ModelicaModel { passed_vars.extend(dep_vars.clone()); for var in passed_vars { if !all_vars.contains(&var) { - return Err(format!("Variable not found in equations: {}", var)); + return bail!("Variable not found in equations: {}", var); } } // check that V = Q + P + M if all_vars.len() != (constants.len() + indep_vars.len() + dep_vars.len()) { - return Err(format!("Variable counts don't add up (V={} Q={} P={} M={})", + return bail!("Variable counts don't add up (V={} Q={} P={} M={})", all_vars.len(), constants.len(), indep_vars.len(), - dep_vars.len())); + dep_vars.len()); } // check that all constants are bound and simple for (name, value) in &constants { match *value { - None => return Err(format!("UnderSpecifiedConstant: {}", name)), + None => bail!("UnderSpecifiedConstant: {}", name), Some(Expr::Integer(_)) | Some(Expr::Float(_)) => (), // Ok, Some(_) => { - return Err(format!("NaiveImplementation: can't handle constant: {}", name)) + bail!("NaiveImplementation: can't handle constant: {}", name); } } } @@ -117,15 +118,14 @@ impl ModelicaModelExt for ModelicaModel { // check that there is a depdendent variable in each equation for eqn in &self.equations { if dep_vars.is_disjoint(&eqn.identifiers()) { - return Err("NaiveImplementation/OverConstrained: at least one equation is \ - missing a dependent variable" - .to_string()); + bail!("NaiveImplementation/OverConstrained: at least one equation is \ + missing a dependent variable") } } // check N >= M if self.equations.len() < dep_vars.len() { - return Err("UnderConstrained: more dependent variables than equations".to_string()); + bail!("UnderConstrained: more dependent variables than equations"); } println!("Soliving for {:?} in terms of params {:?} and constants {:?}, with {} equations", @@ -142,7 +142,7 @@ impl ModelicaModelExt for ModelicaModel { .position(|ref x| unsolved_vars.intersection(&x.identifiers()).count() == 1); let eqn = match next_i { None => { - return Err("NaiveImplementation (or poor equation selection?)".to_string()); + return bail!("NaiveImplementation (or poor equation selection?)"); } Some(i) => unsolved_eqns.remove(i), }; @@ -191,18 +191,18 @@ pub fn substitute_with(original: &Expr, a: &Expr, b: &Expr) -> Expr { } pub trait SimpleEquationExt { - fn rebalance_for(&self, ident: String) -> Result; - fn simplify_lhs(&self, ident: &str) -> Result; + fn rebalance_for(&self, ident: String) -> Result; + fn simplify_lhs(&self, ident: &str) -> Result; } impl SimpleEquationExt for SimpleEquation { - fn rebalance_for(&self, ident: String) -> Result { + fn rebalance_for(&self, ident: String) -> Result { let lvars = self.lhs.identifiers(); let rvars = self.rhs.identifiers(); let ret = match (lvars.contains(&ident), rvars.contains(&ident)) { - (true, true) => Err("SymbolicError: NaiveImplementation".to_string()), - (false, false) => Err("SymbolicError: VariableNotFound".to_string()), + (true, true) => bail!("SymbolicError: NaiveImplementation"), + (false, false) => bail!("SymbolicError: VariableNotFound"), (true, false) => self.simplify_lhs(&ident), (false, true) => { SimpleEquation { @@ -215,7 +215,7 @@ impl SimpleEquationExt for SimpleEquation { match ret { Ok(eqn) => { if eqn.rhs.contains(&ident) { - Err("SymbolicError: NaiveImplementation".to_string()) + bail!("SymbolicError: NaiveImplementation") } else { Ok(eqn) } @@ -224,18 +224,18 @@ impl SimpleEquationExt for SimpleEquation { } } - fn simplify_lhs(&self, ident: &str) -> Result { + fn simplify_lhs(&self, ident: &str) -> Result { use modelica_parser::Expr::*; use modelica_parser::BinOperator::*; match self.lhs { Ident(ref s) if s == ident => Ok((*self).clone()), Ident(_) | Integer(_) | Float(_) | Boolean(_) | StringLiteral(_) => { - Err("SymbolicError: InternalError: expected var on LHS".to_string()) + bail!("SymbolicError: InternalError: expected var on LHS") } Der(_) | MathUnaryExpr(_, _) | Sign(_) | - Array(_) => Err("SymbolicError: NaiveImplementation: can't simplify".to_string()), + Array(_) => bail!("SymbolicError: NaiveImplementation: can't simplify"), // TODO: create a macro for the below... BinExpr(Multiply, ref a, ref b) if a.contains(ident) => { SimpleEquation { @@ -294,8 +294,7 @@ impl SimpleEquationExt for SimpleEquation { .simplify_lhs(&ident) } BinExpr(_, _, _) => { - Err("SymbolicError: NotImplemented BinOperator (or else couldn't find var...)" - .to_string()) + bail!("SymbolicError: NotImplemented BinOperator (or else couldn't find var...)") } // in case we add opers: _ => Err("NotImplemented".to_string()), } diff --git a/src/transpile_js.rs b/src/transpile_js.rs index 5ca16e6..269e900 100644 --- a/src/transpile_js.rs +++ b/src/transpile_js.rs @@ -2,14 +2,15 @@ extern crate modelica_parser; use self::modelica_parser::*; +use errors::Result; pub trait TranspileJS { - fn repr_js(&self) -> Result; + fn repr_js(&self) -> Result; } impl TranspileJS for ModelicaModel { - fn repr_js(&self) -> Result { + fn repr_js(&self) -> Result { let mut constants = vec![]; for (c, e) in self.get_constant_vars() { if let Some(v) = e { @@ -23,8 +24,7 @@ impl TranspileJS for ModelicaModel { binds.push(format!("var {} = {};", symb, try!(eq.rhs.repr_js()))); outputs.push(symb.to_string()); } else { - return Err("Expected an identifier on LHS (in this partial implementation)" - .to_string()); + bail!("Expected an identifier on LHS (in this partial implementation)") } } let args: Vec = self.get_free_vars().iter().map(|s| s.clone()).collect(); @@ -42,7 +42,7 @@ impl TranspileJS for ModelicaModel { } impl TranspileJS for Expr { - fn repr_js(&self) -> Result { + fn repr_js(&self) -> Result { use modelica_parser::Expr::*; match *self { Integer(e) => Ok(format!("{}", e)), @@ -57,7 +57,7 @@ impl TranspileJS for Expr { BinExpr(op, ref l, ref r) => { Ok(format!("({} {:?} {})", try!(l.repr_js()), op, try!(r.repr_js()))) } - Array(_) => Err("Array unimplemented".to_string()), + Array(_) => bail!("Array unimplemented"), } } } diff --git a/src/transpile_scheme.rs b/src/transpile_scheme.rs index 8e6d642..362dfdd 100644 --- a/src/transpile_scheme.rs +++ b/src/transpile_scheme.rs @@ -2,14 +2,15 @@ extern crate modelica_parser; use self::modelica_parser::*; +use errors::Result; pub trait TranspileScheme { - fn repr_scheme(&self) -> Result; + fn repr_scheme(&self) -> Result; } impl TranspileScheme for ModelicaModel { - fn repr_scheme(&self) -> Result { + fn repr_scheme(&self) -> Result { let mut constants = vec![]; for (c, e) in self.get_constant_vars() { if let Some(v) = e { @@ -23,8 +24,7 @@ impl TranspileScheme for ModelicaModel { binds.push(format!("({} {})", symb, try!(eq.rhs.repr_scheme()))); outputs.push(symb.to_string()); } else { - return Err("Expected an identifier on LHS (in this partial implementation)" - .to_string()); + bail!("Expected an identifier on LHS (in this partial implementation)") } } let args: Vec = self.get_free_vars().iter().map(|s| s.clone()).collect(); @@ -40,7 +40,7 @@ impl TranspileScheme for ModelicaModel { } impl TranspileScheme for Expr { - fn repr_scheme(&self) -> Result { + fn repr_scheme(&self) -> Result { use modelica_parser::Expr::*; match *self { Integer(e) => Ok(format!("{}", e)), @@ -58,7 +58,7 @@ impl TranspileScheme for Expr { try!(l.repr_scheme()), try!(r.repr_scheme()))) } - Array(_) => Err("Array unimplemented".to_string()), + Array(_) => bail!("Array unimplemented"), } } } -- cgit v1.2.3