Switch from failure to anyhow (#1851)

This commit switches all of `wasm-bindgen` from the `failure` crate to
`anyhow`. The `anyhow` crate should serve all the purposes that we
previously used `failure` for but has a few advantages:

* It's based on the standard `Error` trait rather than a custom `Fail`
  trait, improving ecosystem compatibility.
* We don't need a `#[derive(Fail)]`, which means that's less code to
  compile for `wasm-bindgen`. This notably helps the compile time of
  `web-sys` itself.
* Using `Result<()>` in `fn main` with `anyhow::Error` produces
  human-readable output, so we can use that natively.
This commit is contained in:
Alex Crichton
2019-11-04 11:35:28 -06:00
committed by GitHub
parent 913fdbc3da
commit 935f71afec
37 changed files with 131 additions and 239 deletions

View File

@ -1,65 +0,0 @@
use failure::{Backtrace, Context, Fail};
use std::fmt;
/// Either `Ok(t)` or `Err(Error)`.
pub type Result<T> = ::std::result::Result<T, Error>;
/// The different contexts an error can occur in in this crate.
#[derive(Debug, Fail, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum ErrorKind {
/// Failed to open a WebIDL file.
#[fail(display = "opening WebIDL file")]
OpeningWebIDLFile,
/// Failed to read a WebIDL file.
#[fail(display = "reading WebIDL file")]
ReadingWebIDLFile,
/// Failed to parse a WebIDL file.
#[fail(display = "parsing WebIDL source text at {}", _0)]
ParsingWebIDLSourcePos(usize),
/// Failed to parse a WebIDL file.
#[fail(display = "parsing WebIDL source text")]
ParsingWebIDLSource,
}
/// The error type for this crate.
#[derive(Debug)]
pub struct Error {
inner: Context<ErrorKind>,
}
impl Fail for Error {
fn cause(&self) -> Option<&dyn Fail> {
self.inner.cause()
}
fn backtrace(&self) -> Option<&Backtrace> {
self.inner.backtrace()
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.inner, f)
}
}
impl Error {
/// The context for this error.
pub fn kind(&self) -> ErrorKind {
*self.inner.get_context()
}
}
impl From<ErrorKind> for Error {
fn from(kind: ErrorKind) -> Error {
Error {
inner: Context::new(kind),
}
}
}
impl From<Context<ErrorKind>> for Error {
fn from(inner: Context<ErrorKind>) -> Error {
Error { inner: inner }
}
}

View File

@ -9,7 +9,6 @@ emitted for the types and methods described in the WebIDL.
#![deny(missing_debug_implementations)]
#![doc(html_root_url = "https://docs.rs/wasm-bindgen-webidl/0.2")]
mod error;
mod first_pass;
mod idl_type;
mod util;
@ -21,11 +20,12 @@ use crate::util::{
camel_case_ident, mdn_doc, public, shouty_snake_case_ident, snake_case_ident,
webidl_const_v_to_backend_const_v, TypePosition,
};
use failure::format_err;
use anyhow::{bail, Result};
use proc_macro2::{Ident, Span};
use quote::{quote, ToTokens};
use std::collections::{BTreeSet, HashSet};
use std::env;
use std::fmt;
use std::fmt::Display;
use std::fs;
use std::iter::FromIterator;
@ -38,22 +38,30 @@ use weedle::attribute::ExtendedAttributeList;
use weedle::dictionary::DictionaryMember;
use weedle::interface::InterfaceMember;
pub use crate::error::{Error, ErrorKind, Result};
struct Program {
main: ast::Program,
submodules: Vec<(String, ast::Program)>,
}
/// A parse error indicating where parsing failed
#[derive(Debug)]
pub struct WebIDLParseError(pub usize);
impl fmt::Display for WebIDLParseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "failed to parse webidl at byte position {}", self.0)
}
}
impl std::error::Error for WebIDLParseError {}
/// Parse a string of WebIDL source text into a wasm-bindgen AST.
fn parse(webidl_source: &str, allowed_types: Option<&[&str]>) -> Result<Program> {
let definitions = match weedle::parse(webidl_source) {
Ok(def) => def,
Err(e) => {
return Err(match &e {
weedle::Err::Incomplete(needed) => format_err!("needed {:?} more bytes", needed)
.context(ErrorKind::ParsingWebIDLSource)
.into(),
match &e {
weedle::Err::Incomplete(needed) => bail!("needed {:?} more bytes", needed),
weedle::Err::Error(cx) | weedle::Err::Failure(cx) => {
// Note that #[allow] here is a workaround for Geal/nom#843
// because the `Context` type here comes from `nom` and if
@ -66,11 +74,10 @@ fn parse(webidl_source: &str, allowed_types: Option<&[&str]>) -> Result<Program>
_ => 0,
};
let pos = webidl_source.len() - remaining;
format_err!("failed to parse WebIDL")
.context(ErrorKind::ParsingWebIDLSourcePos(pos))
.into()
bail!(WebIDLParseError(pos))
}
});
}
}
};