diff --git a/Cargo.lock b/Cargo.lock index fdee0b8ebe8..3d1d1cb200b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -175,6 +175,25 @@ dependencies = [ "backtrace 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "failure" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "failure_derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fuchsia-zircon" version = "0.3.3" @@ -309,6 +328,11 @@ name = "quick-error" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "quote" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "quote" version = "0.5.2" @@ -453,6 +477,7 @@ dependencies = [ "derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -566,6 +591,16 @@ name = "stable_deref_trait" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "syn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "syn" version = "0.13.1" @@ -576,6 +611,23 @@ dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "synom" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "synstructure" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tempdir" version = "0.3.7" @@ -653,6 +705,11 @@ name = "unicode-width" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unicode-xid" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-xid" version = "0.1.0" @@ -747,6 +804,8 @@ dependencies = [ "checksum env_logger 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)" = "00c45cec4cde3daac5f036c74098b4956151525cdf360cff5ee0092c98823e54" "checksum environment 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4b14e20978669064c33b4c1e0fb4083412e40fe56cbea2eae80fd7591503ee" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" +"checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" +"checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "b900c08c1939860ce8b54dc6a89e26e00c04c380fd0e09796799bd7f12861e05" @@ -766,6 +825,7 @@ dependencies = [ "checksum proc-macro2 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b16749538926f394755373f0dfec0852d79b3bd512a5906ceaeb72ee64a4eaa0" "checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32" "checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4" +"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" "checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" @@ -792,7 +852,10 @@ dependencies = [ "checksum skeptic 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c8431f8fca168e2db4be547bd8329eac70d095dff1444fee4b0fa0fabc7df75a" "checksum smallvec 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03dab98ab5ded3a8b43b2c80751194608d0b2aa0f1d46cf95d1c35e192844aa7" "checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b" +"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "91b52877572087400e83d24b9178488541e3d535259e04ff17a63df1e5ceff59" +"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" +"checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" "checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561" @@ -803,6 +866,7 @@ dependencies = [ "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d" "checksum unicode-segmentation 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a8083c594e02b8ae1654ae26f0ade5158b119bd88ad0e8227a5d8fcd72407946" "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" +"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" diff --git a/Cargo.toml b/Cargo.toml index 0924527f372..4074f67b875 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,6 +47,7 @@ getopts = "0.2" derive-new = "0.5" cargo_metadata = "0.5.1" rustc-ap-syntax = "110.0.0" +failure = "0.1.1" [dev-dependencies] assert_cli = "0.5" diff --git a/src/bin/main.rs b/src/bin/main.rs index 453c7806d23..0ddf2f8c3df 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -11,6 +11,7 @@ #![cfg(not(test))] extern crate env_logger; +extern crate failure; extern crate getopts; extern crate rustfmt_nightly as rustfmt; @@ -19,6 +20,8 @@ use std::io::{self, stdout, Read, Write}; use std::path::PathBuf; +use failure::err_msg; + use getopts::{Matches, Options}; use rustfmt::{emit_post_matter, emit_pre_matter, load_config, CliOptions, Config, FmtResult, @@ -167,7 +170,7 @@ fn execute(opts: &Options) -> FmtResult<(WriteMode, Summary)> { Ok((WriteMode::None, Summary::default())) } Operation::ConfigOutputDefault { path } => { - let toml = Config::default().all_options().to_toml()?; + let toml = Config::default().all_options().to_toml().map_err(err_msg)?; if let Some(path) = path { let mut file = File::create(path)?; file.write_all(toml.as_bytes())?; @@ -186,7 +189,9 @@ fn execute(opts: &Options) -> FmtResult<(WriteMode, Summary)> { // parse file_lines if let Some(ref file_lines) = matches.opt_str("file-lines") { - config.set().file_lines(file_lines.parse()?); + config + .set() + .file_lines(file_lines.parse().map_err(err_msg)?); for f in config.file_lines().files() { match *f { FileName::Custom(ref f) if f == "stdin" => {} @@ -273,7 +278,7 @@ fn format( // that were used during formatting as TOML. if let Some(path) = minimal_config_path { let mut file = File::create(path)?; - let toml = config.used_options().to_toml()?; + let toml = config.used_options().to_toml().map_err(err_msg)?; file.write_all(toml.as_bytes())?; } diff --git a/src/config/mod.rs b/src/config/mod.rs index 8dde1e05c3d..23897f3cc32 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -16,8 +16,6 @@ use std::path::{Path, PathBuf}; use std::{env, fs}; -use {FmtError, FmtResult}; - use config::config_type::ConfigType; use config::file_lines::FileLines; pub use config::lists::*; @@ -154,18 +152,16 @@ pub fn load_config( file_path: Option<&Path>, options: Option<&CliOptions>, -) -> FmtResult<(Config, Option)> { +) -> Result<(Config, Option), Error> { let over_ride = match options { Some(opts) => config_path(opts)?, None => None, }; let result = if let Some(over_ride) = over_ride { - Config::from_toml_path(over_ride.as_ref()) - .map(|p| (p, Some(over_ride.to_owned()))) - .map_err(FmtError::from) + Config::from_toml_path(over_ride.as_ref()).map(|p| (p, Some(over_ride.to_owned()))) } else if let Some(file_path) = file_path { - Config::from_resolved_toml_path(file_path).map_err(FmtError::from) + Config::from_resolved_toml_path(file_path) } else { Ok((Config::default(), None)) }; @@ -202,12 +198,15 @@ fn get_toml_path(dir: &Path) -> Result, Error> { Ok(None) } -fn config_path(options: &CliOptions) -> FmtResult> { - let config_path_not_found = |path: &str| -> FmtResult> { - Err(FmtError::from(format!( - "Error: unable to find a config file for the given path: `{}`", - path - ))) +fn config_path(options: &CliOptions) -> Result, Error> { + let config_path_not_found = |path: &str| -> Result, Error> { + Err(Error::new( + ErrorKind::NotFound, + format!( + "Error: unable to find a config file for the given path: `{}`", + path + ), + )) }; // Read the config_path and convert to parent dir if a file is provided. diff --git a/src/config/options.rs b/src/config/options.rs index 73dbdb88663..9721815eeee 100644 --- a/src/config/options.rs +++ b/src/config/options.rs @@ -14,7 +14,9 @@ use config::file_lines::FileLines; use config::lists::*; use config::Config; -use {FmtError, FmtResult, WRITE_MODE_LIST}; +use {FmtResult, WRITE_MODE_LIST}; + +use failure::err_msg; use getopts::Matches; use std::collections::HashSet; @@ -332,8 +334,8 @@ pub fn from_matches(matches: &Matches) -> FmtResult { .map(|c| c == "nightly") .unwrap_or(false); if unstable_features && !rust_nightly { - return Err(FmtError::from( - "Unstable features are only available on Nightly channel", + return Err(format_err!( + "Unstable features are only available on Nightly channel" )); } else { options.unstable_features = unstable_features; @@ -345,22 +347,23 @@ pub fn from_matches(matches: &Matches) -> FmtResult { if let Ok(write_mode) = WriteMode::from_str(write_mode) { options.write_mode = Some(write_mode); } else { - return Err(FmtError::from(format!( + return Err(format_err!( "Invalid write-mode: {}, expected one of {}", - write_mode, WRITE_MODE_LIST - ))); + write_mode, + WRITE_MODE_LIST + )); } } if let Some(ref color) = matches.opt_str("color") { match Color::from_str(color) { Ok(color) => options.color = Some(color), - _ => return Err(FmtError::from(format!("Invalid color: {}", color))), + _ => return Err(format_err!("Invalid color: {}", color)), } } if let Some(ref file_lines) = matches.opt_str("file-lines") { - options.file_lines = file_lines.parse()?; + options.file_lines = file_lines.parse().map_err(err_msg)?; } if matches.opt_present("skip-children") { diff --git a/src/format-diff/main.rs b/src/format-diff/main.rs index 402f7ab507a..fe528a6c0ea 100644 --- a/src/format-diff/main.rs +++ b/src/format-diff/main.rs @@ -15,6 +15,8 @@ #![deny(warnings)] extern crate env_logger; +#[macro_use] +extern crate failure; extern crate getopts; #[macro_use] extern crate log; @@ -24,9 +26,8 @@ extern crate serde_json as json; use std::collections::HashSet; -use std::error::Error; use std::io::{self, BufRead}; -use std::{env, fmt, process}; +use std::{env, process}; use regex::Regex; @@ -35,31 +36,14 @@ /// We only want to format rust files by default. const DEFAULT_PATTERN: &str = r".*\.rs"; -#[derive(Debug)] +#[derive(Fail, Debug)] enum FormatDiffError { - IncorrectOptions(getopts::Fail), - IncorrectFilter(regex::Error), - IoError(io::Error), -} - -impl fmt::Display for FormatDiffError { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - fmt::Display::fmt(self.cause().unwrap(), f) - } -} - -impl Error for FormatDiffError { - fn description(&self) -> &str { - self.cause().unwrap().description() - } - - fn cause(&self) -> Option<&Error> { - Some(match *self { - FormatDiffError::IoError(ref e) => e, - FormatDiffError::IncorrectFilter(ref e) => e, - FormatDiffError::IncorrectOptions(ref e) => e, - }) - } + #[fail(display = "{}", _0)] + IncorrectOptions(#[cause] getopts::Fail), + #[fail(display = "{}", _0)] + IncorrectFilter(#[cause] regex::Error), + #[fail(display = "{}", _0)] + IoError(#[cause] io::Error), } impl From for FormatDiffError { @@ -99,7 +83,7 @@ fn main() { ); if let Err(e) = run(&opts) { - println!("{}", opts.usage(e.description())); + println!("{}", opts.usage(&format!("{}", e))); process::exit(1); } } diff --git a/src/lib.rs b/src/lib.rs index 0a5c7307e4f..b272402b20f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,6 +19,8 @@ #[macro_use] extern crate derive_new; extern crate diff; +#[macro_use] +extern crate failure; extern crate getopts; extern crate itertools; #[cfg(test)] @@ -37,7 +39,6 @@ extern crate unicode_segmentation; use std::collections::HashMap; -use std::error; use std::fmt; use std::io::{self, stdout, Write}; use std::panic::{catch_unwind, AssertUnwindSafe}; @@ -53,6 +54,7 @@ use syntax::parse::{self, ParseSess}; use comment::{CharClasses, FullCodeCharKind, LineClasses}; +use failure::Fail; use issues::{BadIssueSeeker, Issue}; use shape::Indent; use utils::use_colored_tty; @@ -62,8 +64,7 @@ pub use config::summary::Summary; pub use config::{file_lines, load_config, Config, WriteMode}; -pub type FmtError = Box; -pub type FmtResult = std::result::Result; +pub type FmtResult = std::result::Result; pub const WRITE_MODE_LIST: &str = "[replace|overwrite|display|plain|diff|coverage|checkstyle|check]"; @@ -109,33 +110,26 @@ pub(crate) type FileRecord = (FileName, String); -#[derive(Clone, Copy)] +#[derive(Fail, Debug, Clone, Copy)] pub enum ErrorKind { // Line has exceeded character limit (found, maximum) + #[fail( + display = "line formatted, but exceeded maximum width (maximum: {} (see `max_width` option), found: {})", + _0, + _1 + )] LineOverflow(usize, usize), // Line ends in whitespace + #[fail(display = "left behind trailing whitespace")] TrailingWhitespace, // TODO or FIXME item without an issue number + #[fail(display = "found {}", _0)] BadIssue(Issue), // License check has failed + #[fail(display = "license check failed")] LicenseCheck, } -impl fmt::Display for ErrorKind { - fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { - match *self { - ErrorKind::LineOverflow(found, maximum) => write!( - fmt, - "line formatted, but exceeded maximum width (maximum: {} (see `max_width` option), found: {})", - maximum, found, - ), - ErrorKind::TrailingWhitespace => write!(fmt, "left behind trailing whitespace"), - ErrorKind::BadIssue(issue) => write!(fmt, "found {}", issue), - ErrorKind::LicenseCheck => write!(fmt, "license check failed"), - } - } -} - // Formatting errors that are identified *after* rustfmt has run. struct FormattingError { line: usize, @@ -901,7 +895,7 @@ pub enum Input { pub fn format_and_emit_report(input: Input, config: &Config) -> FmtResult { if !config.version_meets_requirement() { - return Err(FmtError::from("Version mismatch")); + return Err(format_err!("Version mismatch")); } let out = &mut stdout(); match format_input(input, config, Some(out)) {