Skip to content

Commit bc9a0b2

Browse files
dtolnaycalebcartwright
authored andcommitted
Switch to std::error::Error for errors (#3948)
1 parent b28fd5f commit bc9a0b2

File tree

7 files changed

+93
-70
lines changed

7 files changed

+93
-70
lines changed

Cargo.lock

+28-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ env_logger = "0.6"
4747
getopts = "0.2"
4848
derive-new = "0.5"
4949
cargo_metadata = "0.8"
50-
failure = "0.1.3"
5150
bytecount = "0.6"
5251
unicode-width = "0.1.5"
5352
unicode_categories = "0.1.1"
@@ -57,6 +56,8 @@ annotate-snippets = { version = "0.6", features = ["ansi_term"] }
5756
structopt = "0.3"
5857
rustfmt-config_proc_macro = { version = "0.2", path = "config_proc_macro" }
5958
lazy_static = "1.0.0"
59+
anyhow = "1.0"
60+
thiserror = "1.0"
6061

6162
# A noop dependency that changes in the Rust repository, it's a bit of a hack.
6263
# See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust`

src/bin/main.rs

+19-18
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
use anyhow::{format_err, Result};
12
use env_logger;
2-
use failure::{err_msg, format_err, Error as FailureError, Fail};
33
use io::Error as IoError;
4+
use thiserror::Error;
45

56
use rustfmt_nightly as rustfmt;
67

@@ -59,27 +60,27 @@ enum Operation {
5960
}
6061

6162
/// Rustfmt operations errors.
62-
#[derive(Fail, Debug)]
63+
#[derive(Error, Debug)]
6364
pub enum OperationError {
6465
/// An unknown help topic was requested.
65-
#[fail(display = "Unknown help topic: `{}`.", _0)]
66+
#[error("Unknown help topic: `{0}`.")]
6667
UnknownHelpTopic(String),
6768
/// An unknown print-config option was requested.
68-
#[fail(display = "Unknown print-config option: `{}`.", _0)]
69+
#[error("Unknown print-config option: `{0}`.")]
6970
UnknownPrintConfigTopic(String),
7071
/// Attempt to generate a minimal config from standard input.
71-
#[fail(display = "The `--print-config=minimal` option doesn't work with standard input.")]
72+
#[error("The `--print-config=minimal` option doesn't work with standard input.")]
7273
MinimalPathWithStdin,
7374
/// An io error during reading or writing.
74-
#[fail(display = "io error: {}", _0)]
75+
#[error("io error: {0}")]
7576
IoError(IoError),
7677
/// Attempt to use --check with stdin, which isn't currently
7778
/// supported.
78-
#[fail(display = "The `--check` option is not supported with standard input.")]
79+
#[error("The `--check` option is not supported with standard input.")]
7980
CheckWithStdin,
8081
/// Attempt to use --emit=json with stdin, which isn't currently
8182
/// supported.
82-
#[fail(display = "Using `--emit` other than stdout is not supported with standard input.")]
83+
#[error("Using `--emit` other than stdout is not supported with standard input.")]
8384
EmitWithStdin,
8485
}
8586

@@ -192,7 +193,7 @@ fn is_nightly() -> bool {
192193
}
193194

194195
// Returned i32 is an exit code
195-
fn execute(opts: &Options) -> Result<i32, FailureError> {
196+
fn execute(opts: &Options) -> Result<i32> {
196197
let matches = opts.parse(env::args().skip(1))?;
197198
let options = GetOptsOptions::from_matches(&matches)?;
198199

@@ -214,7 +215,7 @@ fn execute(opts: &Options) -> Result<i32, FailureError> {
214215
Ok(0)
215216
}
216217
Operation::ConfigOutputDefault { path } => {
217-
let toml = Config::default().all_options().to_toml().map_err(err_msg)?;
218+
let toml = Config::default().all_options().to_toml()?;
218219
if let Some(path) = path {
219220
let mut file = File::create(path)?;
220221
file.write_all(toml.as_bytes())?;
@@ -233,7 +234,7 @@ fn execute(opts: &Options) -> Result<i32, FailureError> {
233234
let file = file.canonicalize().unwrap_or(file);
234235

235236
let (config, _) = load_config(Some(file.parent().unwrap()), Some(options.clone()))?;
236-
let toml = config.all_options().to_toml().map_err(err_msg)?;
237+
let toml = config.all_options().to_toml()?;
237238
io::stdout().write_all(toml.as_bytes())?;
238239

239240
Ok(0)
@@ -246,7 +247,7 @@ fn execute(opts: &Options) -> Result<i32, FailureError> {
246247
}
247248
}
248249

249-
fn format_string(input: String, options: GetOptsOptions) -> Result<i32, FailureError> {
250+
fn format_string(input: String, options: GetOptsOptions) -> Result<i32> {
250251
// try to read config from local directory
251252
let (mut config, _) = load_config(Some(Path::new(".")), Some(options.clone()))?;
252253

@@ -287,7 +288,7 @@ fn format(
287288
files: Vec<PathBuf>,
288289
minimal_config_path: Option<String>,
289290
options: &GetOptsOptions,
290-
) -> Result<i32, FailureError> {
291+
) -> Result<i32> {
291292
options.verify_file_lines(&files);
292293
let (config, config_path) = load_config(None, Some(options.clone()))?;
293294

@@ -335,7 +336,7 @@ fn format(
335336
// that were used during formatting as TOML.
336337
if let Some(path) = minimal_config_path {
337338
let mut file = File::create(path)?;
338-
let toml = session.config.used_options().to_toml().map_err(err_msg)?;
339+
let toml = session.config.used_options().to_toml()?;
339340
file.write_all(toml.as_bytes())?;
340341
}
341342

@@ -514,7 +515,7 @@ struct GetOptsOptions {
514515
}
515516

516517
impl GetOptsOptions {
517-
pub fn from_matches(matches: &Matches) -> Result<GetOptsOptions, FailureError> {
518+
pub fn from_matches(matches: &Matches) -> Result<GetOptsOptions> {
518519
let mut options = GetOptsOptions::default();
519520
options.verbose = matches.opt_present("verbose");
520521
options.quiet = matches.opt_present("quiet");
@@ -535,7 +536,7 @@ impl GetOptsOptions {
535536
options.error_on_unformatted = Some(true);
536537
}
537538
if let Some(ref file_lines) = matches.opt_str("file-lines") {
538-
options.file_lines = file_lines.parse().map_err(err_msg)?;
539+
options.file_lines = file_lines.parse()?;
539540
}
540541
} else {
541542
let mut unstable_options = vec![];
@@ -684,15 +685,15 @@ impl CliOptions for GetOptsOptions {
684685
}
685686
}
686687

687-
fn edition_from_edition_str(edition_str: &str) -> Result<Edition, FailureError> {
688+
fn edition_from_edition_str(edition_str: &str) -> Result<Edition> {
688689
match edition_str {
689690
"2015" => Ok(Edition::Edition2015),
690691
"2018" => Ok(Edition::Edition2018),
691692
_ => Err(format_err!("Invalid value for `--edition`")),
692693
}
693694
}
694695

695-
fn emit_mode_from_emit_str(emit_str: &str) -> Result<EmitMode, FailureError> {
696+
fn emit_mode_from_emit_str(emit_str: &str) -> Result<EmitMode> {
696697
match emit_str {
697698
"files" => Ok(EmitMode::Files),
698699
"stdout" => Ok(EmitMode::Stdout),

src/config/file_lines.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use std::{cmp, fmt, iter, str};
99
use rustc_span::{self, SourceFile};
1010
use serde::{ser, Deserialize, Deserializer, Serialize, Serializer};
1111
use serde_json as json;
12+
use thiserror::Error;
1213

1314
/// A range of lines in a file, inclusive of both ends.
1415
pub struct LineRange {
@@ -287,12 +288,20 @@ fn canonicalize_path_string(file: &FileName) -> Option<FileName> {
287288
}
288289
}
289290

291+
#[derive(Error, Debug)]
292+
pub enum FileLinesError {
293+
#[error("{0}")]
294+
Json(json::Error),
295+
#[error("Can't canonicalize {0}")]
296+
CannotCanonicalize(FileName),
297+
}
298+
290299
// This impl is needed for `Config::override_value` to work for use in tests.
291300
impl str::FromStr for FileLines {
292-
type Err = String;
301+
type Err = FileLinesError;
293302

294-
fn from_str(s: &str) -> Result<FileLines, String> {
295-
let v: Vec<JsonSpan> = json::from_str(s).map_err(|e| e.to_string())?;
303+
fn from_str(s: &str) -> Result<FileLines, Self::Err> {
304+
let v: Vec<JsonSpan> = json::from_str(s).map_err(FileLinesError::Json)?;
296305
let mut m = HashMap::new();
297306
for js in v {
298307
let (s, r) = JsonSpan::into_tuple(js)?;
@@ -310,10 +319,10 @@ pub struct JsonSpan {
310319
}
311320

312321
impl JsonSpan {
313-
fn into_tuple(self) -> Result<(FileName, Range), String> {
322+
fn into_tuple(self) -> Result<(FileName, Range), FileLinesError> {
314323
let (lo, hi) = self.range;
315324
let canonical = canonicalize_path_string(&self.file)
316-
.ok_or_else(|| format!("Can't canonicalize {}", &self.file))?;
325+
.ok_or_else(|| FileLinesError::CannotCanonicalize(self.file))?;
317326
Ok((canonical, Range::new(lo, hi)))
318327
}
319328
}

src/config/mod.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::path::{Path, PathBuf};
66
use std::{env, fs};
77

88
use regex::Regex;
9+
use thiserror::Error;
910

1011
use crate::config::config_type::ConfigType;
1112
#[allow(unreachable_pub)]
@@ -157,16 +158,20 @@ create_config! {
157158
files that would be formated when used with `--check` mode. ";
158159
}
159160

161+
#[derive(Error, Debug)]
162+
#[error("Could not output config: {0}")]
163+
pub struct ToTomlError(toml::ser::Error);
164+
160165
impl PartialConfig {
161-
pub fn to_toml(&self) -> Result<String, String> {
166+
pub fn to_toml(&self) -> Result<String, ToTomlError> {
162167
// Non-user-facing options can't be specified in TOML
163168
let mut cloned = self.clone();
164169
cloned.file_lines = None;
165170
cloned.verbose = None;
166171
cloned.width_heuristics = None;
167172
cloned.print_misformatted_file_names = None;
168173

169-
::toml::to_string(&cloned).map_err(|e| format!("Could not output config: {}", e))
174+
::toml::to_string(&cloned).map_err(ToTomlError)
170175
}
171176
}
172177

src/format-diff/main.rs

+8-27
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@
66

77
use env_logger;
88
#[macro_use]
9-
extern crate failure;
10-
#[macro_use]
119
extern crate log;
1210
use regex;
1311
use serde::{Deserialize, Serialize};
1412
use serde_json as json;
13+
use thiserror::Error;
1514

1615
use std::collections::HashSet;
1716
use std::io::{self, BufRead};
@@ -27,32 +26,14 @@ use structopt::StructOpt;
2726
/// We only want to format rust files by default.
2827
const DEFAULT_PATTERN: &str = r".*\.rs";
2928

30-
#[derive(Fail, Debug)]
29+
#[derive(Error, Debug)]
3130
enum FormatDiffError {
32-
#[fail(display = "{}", _0)]
33-
IncorrectOptions(#[cause] getopts::Fail),
34-
#[fail(display = "{}", _0)]
35-
IncorrectFilter(#[cause] regex::Error),
36-
#[fail(display = "{}", _0)]
37-
IoError(#[cause] io::Error),
38-
}
39-
40-
impl From<getopts::Fail> for FormatDiffError {
41-
fn from(fail: getopts::Fail) -> Self {
42-
FormatDiffError::IncorrectOptions(fail)
43-
}
44-
}
45-
46-
impl From<regex::Error> for FormatDiffError {
47-
fn from(err: regex::Error) -> Self {
48-
FormatDiffError::IncorrectFilter(err)
49-
}
50-
}
51-
52-
impl From<io::Error> for FormatDiffError {
53-
fn from(fail: io::Error) -> Self {
54-
FormatDiffError::IoError(fail)
55-
}
31+
#[error("{0}")]
32+
IncorrectOptions(#[from] getopts::Fail),
33+
#[error("{0}")]
34+
IncorrectFilter(#[from] regex::Error),
35+
#[error("{0}")]
36+
IoError(#[from] io::Error),
5637
}
5738

5839
#[derive(StructOpt, Debug)]

0 commit comments

Comments
 (0)