Skip to content

Commit

Permalink
Switch to std::error::Error for errors (rust-lang#3948)
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay authored and calebcartwright committed Jun 12, 2020
1 parent b28fd5f commit bc9a0b2
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 70 deletions.
29 changes: 28 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ env_logger = "0.6"
getopts = "0.2"
derive-new = "0.5"
cargo_metadata = "0.8"
failure = "0.1.3"
bytecount = "0.6"
unicode-width = "0.1.5"
unicode_categories = "0.1.1"
Expand All @@ -57,6 +56,8 @@ annotate-snippets = { version = "0.6", features = ["ansi_term"] }
structopt = "0.3"
rustfmt-config_proc_macro = { version = "0.2", path = "config_proc_macro" }
lazy_static = "1.0.0"
anyhow = "1.0"
thiserror = "1.0"

# A noop dependency that changes in the Rust repository, it's a bit of a hack.
# See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust`
Expand Down
37 changes: 19 additions & 18 deletions src/bin/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use anyhow::{format_err, Result};
use env_logger;
use failure::{err_msg, format_err, Error as FailureError, Fail};
use io::Error as IoError;
use thiserror::Error;

use rustfmt_nightly as rustfmt;

Expand Down Expand Up @@ -59,27 +60,27 @@ enum Operation {
}

/// Rustfmt operations errors.
#[derive(Fail, Debug)]
#[derive(Error, Debug)]
pub enum OperationError {
/// An unknown help topic was requested.
#[fail(display = "Unknown help topic: `{}`.", _0)]
#[error("Unknown help topic: `{0}`.")]
UnknownHelpTopic(String),
/// An unknown print-config option was requested.
#[fail(display = "Unknown print-config option: `{}`.", _0)]
#[error("Unknown print-config option: `{0}`.")]
UnknownPrintConfigTopic(String),
/// Attempt to generate a minimal config from standard input.
#[fail(display = "The `--print-config=minimal` option doesn't work with standard input.")]
#[error("The `--print-config=minimal` option doesn't work with standard input.")]
MinimalPathWithStdin,
/// An io error during reading or writing.
#[fail(display = "io error: {}", _0)]
#[error("io error: {0}")]
IoError(IoError),
/// Attempt to use --check with stdin, which isn't currently
/// supported.
#[fail(display = "The `--check` option is not supported with standard input.")]
#[error("The `--check` option is not supported with standard input.")]
CheckWithStdin,
/// Attempt to use --emit=json with stdin, which isn't currently
/// supported.
#[fail(display = "Using `--emit` other than stdout is not supported with standard input.")]
#[error("Using `--emit` other than stdout is not supported with standard input.")]
EmitWithStdin,
}

Expand Down Expand Up @@ -192,7 +193,7 @@ fn is_nightly() -> bool {
}

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

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

let (config, _) = load_config(Some(file.parent().unwrap()), Some(options.clone()))?;
let toml = config.all_options().to_toml().map_err(err_msg)?;
let toml = config.all_options().to_toml()?;
io::stdout().write_all(toml.as_bytes())?;

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

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

Expand Down Expand Up @@ -287,7 +288,7 @@ fn format(
files: Vec<PathBuf>,
minimal_config_path: Option<String>,
options: &GetOptsOptions,
) -> Result<i32, FailureError> {
) -> Result<i32> {
options.verify_file_lines(&files);
let (config, config_path) = load_config(None, Some(options.clone()))?;

Expand Down Expand Up @@ -335,7 +336,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 = session.config.used_options().to_toml().map_err(err_msg)?;
let toml = session.config.used_options().to_toml()?;
file.write_all(toml.as_bytes())?;
}

Expand Down Expand Up @@ -514,7 +515,7 @@ struct GetOptsOptions {
}

impl GetOptsOptions {
pub fn from_matches(matches: &Matches) -> Result<GetOptsOptions, FailureError> {
pub fn from_matches(matches: &Matches) -> Result<GetOptsOptions> {
let mut options = GetOptsOptions::default();
options.verbose = matches.opt_present("verbose");
options.quiet = matches.opt_present("quiet");
Expand All @@ -535,7 +536,7 @@ impl GetOptsOptions {
options.error_on_unformatted = Some(true);
}
if let Some(ref file_lines) = matches.opt_str("file-lines") {
options.file_lines = file_lines.parse().map_err(err_msg)?;
options.file_lines = file_lines.parse()?;
}
} else {
let mut unstable_options = vec![];
Expand Down Expand Up @@ -684,15 +685,15 @@ impl CliOptions for GetOptsOptions {
}
}

fn edition_from_edition_str(edition_str: &str) -> Result<Edition, FailureError> {
fn edition_from_edition_str(edition_str: &str) -> Result<Edition> {
match edition_str {
"2015" => Ok(Edition::Edition2015),
"2018" => Ok(Edition::Edition2018),
_ => Err(format_err!("Invalid value for `--edition`")),
}
}

fn emit_mode_from_emit_str(emit_str: &str) -> Result<EmitMode, FailureError> {
fn emit_mode_from_emit_str(emit_str: &str) -> Result<EmitMode> {
match emit_str {
"files" => Ok(EmitMode::Files),
"stdout" => Ok(EmitMode::Stdout),
Expand Down
19 changes: 14 additions & 5 deletions src/config/file_lines.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::{cmp, fmt, iter, str};
use rustc_span::{self, SourceFile};
use serde::{ser, Deserialize, Deserializer, Serialize, Serializer};
use serde_json as json;
use thiserror::Error;

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

#[derive(Error, Debug)]
pub enum FileLinesError {
#[error("{0}")]
Json(json::Error),
#[error("Can't canonicalize {0}")]
CannotCanonicalize(FileName),
}

// This impl is needed for `Config::override_value` to work for use in tests.
impl str::FromStr for FileLines {
type Err = String;
type Err = FileLinesError;

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

impl JsonSpan {
fn into_tuple(self) -> Result<(FileName, Range), String> {
fn into_tuple(self) -> Result<(FileName, Range), FileLinesError> {
let (lo, hi) = self.range;
let canonical = canonicalize_path_string(&self.file)
.ok_or_else(|| format!("Can't canonicalize {}", &self.file))?;
.ok_or_else(|| FileLinesError::CannotCanonicalize(self.file))?;
Ok((canonical, Range::new(lo, hi)))
}
}
Expand Down
9 changes: 7 additions & 2 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::path::{Path, PathBuf};
use std::{env, fs};

use regex::Regex;
use thiserror::Error;

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

#[derive(Error, Debug)]
#[error("Could not output config: {0}")]
pub struct ToTomlError(toml::ser::Error);

impl PartialConfig {
pub fn to_toml(&self) -> Result<String, String> {
pub fn to_toml(&self) -> Result<String, ToTomlError> {
// Non-user-facing options can't be specified in TOML
let mut cloned = self.clone();
cloned.file_lines = None;
cloned.verbose = None;
cloned.width_heuristics = None;
cloned.print_misformatted_file_names = None;

::toml::to_string(&cloned).map_err(|e| format!("Could not output config: {}", e))
::toml::to_string(&cloned).map_err(ToTomlError)
}
}

Expand Down
35 changes: 8 additions & 27 deletions src/format-diff/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@

use env_logger;
#[macro_use]
extern crate failure;
#[macro_use]
extern crate log;
use regex;
use serde::{Deserialize, Serialize};
use serde_json as json;
use thiserror::Error;

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

#[derive(Fail, Debug)]
#[derive(Error, Debug)]
enum FormatDiffError {
#[fail(display = "{}", _0)]
IncorrectOptions(#[cause] getopts::Fail),
#[fail(display = "{}", _0)]
IncorrectFilter(#[cause] regex::Error),
#[fail(display = "{}", _0)]
IoError(#[cause] io::Error),
}

impl From<getopts::Fail> for FormatDiffError {
fn from(fail: getopts::Fail) -> Self {
FormatDiffError::IncorrectOptions(fail)
}
}

impl From<regex::Error> for FormatDiffError {
fn from(err: regex::Error) -> Self {
FormatDiffError::IncorrectFilter(err)
}
}

impl From<io::Error> for FormatDiffError {
fn from(fail: io::Error) -> Self {
FormatDiffError::IoError(fail)
}
#[error("{0}")]
IncorrectOptions(#[from] getopts::Fail),
#[error("{0}")]
IncorrectFilter(#[from] regex::Error),
#[error("{0}")]
IoError(#[from] io::Error),
}

#[derive(StructOpt, Debug)]
Expand Down
Loading

0 comments on commit bc9a0b2

Please sign in to comment.