macro: cleanup error handling, remove error module

syn::Error already covers this

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2019-07-18 14:41:26 +02:00
parent 09eaef022f
commit 4b3333aa5c
5 changed files with 28 additions and 44 deletions

View File

@ -16,7 +16,7 @@ pub fn api_macro(attr: TokenStream, item: TokenStream) -> Result<TokenStream, Er
let definition = match definition {
TokenTree::Group(ref group) if group.delimiter() == Delimiter::Brace => group.stream(),
_ => c_bail!(definition.span() => "expected api definition in braces"),
_ => c_bail!(definition => "expected api definition in braces"),
};
let def_span = definition.span();
@ -24,7 +24,7 @@ pub fn api_macro(attr: TokenStream, item: TokenStream) -> Result<TokenStream, Er
// Now parse the item, based on which we decide whether this is an API method which needs a
// wrapper, or an API type which needs an ApiType implementation!
let item: syn::Item = syn::parse2(item).unwrap();
let mut item: syn::Item = syn::parse2(item).unwrap();
match item {
syn::Item::Struct(ref itemstruct) => {
@ -34,13 +34,13 @@ pub fn api_macro(attr: TokenStream, item: TokenStream) -> Result<TokenStream, Er
Ok(output)
}
syn::Item::Fn(func) => handle_function(def_span, definition, func),
syn::Item::Enum(ref itemenum) => {
syn::Item::Enum(ref mut itemenum) => {
let extra = handle_enum(definition, itemenum)?;
let mut output = item.into_token_stream();
output.extend(extra);
Ok(output)
}
_ => c_bail!(item.span() => "api macro currently only applies to structs and functions"),
_ => c_bail!(item => "api macro currently only applies to structs and functions"),
}
}
@ -573,7 +573,7 @@ fn handle_named_struct_fields(
///
/// For enums we automatically implement `ToString`, `FromStr`, and derive `Serialize` and
/// `Deserialize` via `serde_plain`.
fn handle_enum(mut definition: Object, item: &syn::ItemEnum) -> Result<TokenStream, Error> {
fn handle_enum(mut definition: Object, item: &mut syn::ItemEnum) -> Result<TokenStream, Error> {
if item.generics.lt_token.is_some() {
c_bail!(
item.generics.span(),
@ -588,7 +588,7 @@ fn handle_enum(mut definition: Object, item: &syn::ItemEnum) -> Result<TokenStre
let mut display_entries = TokenStream::new();
let mut from_str_entries = TokenStream::new();
for variant in item.variants.iter() {
for variant in item.variants.iter_mut() {
if variant.fields != syn::Fields::Unit {
c_bail!(variant.span(), "#[api] enums cannot have fields");
}
@ -610,7 +610,7 @@ fn handle_enum(mut definition: Object, item: &syn::ItemEnum) -> Result<TokenStre
let apidef = ParameterDefinition::from_object(definition)?;
if let Some(validate) = apidef.validate {
c_bail!(validate.span() => "validators are not allowed on enum types");
c_bail!(validate => "validators are not allowed on enum types");
}
let description = common.description;

View File

@ -1,31 +0,0 @@
#[derive(Debug)]
pub struct CompileError {
pub tokens: proc_macro::TokenStream,
}
unsafe impl Send for CompileError {}
unsafe impl Sync for CompileError {}
impl std::fmt::Display for CompileError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "generic compile error")
}
}
impl std::error::Error for CompileError {}
macro_rules! c_format_err {
($span:expr => $($msg:tt)*) => {
crate::error::CompileError {
tokens: ::quote::quote_spanned! { $span => compile_error!($($msg)*); }.into()
}
};
($span:expr, $($msg:tt)*) => { c_format_err!($span => $($msg)*) }
}
macro_rules! c_bail {
($span:expr => $($msg:tt)*) => {
return Err(c_format_err!($span => $($msg)*).into());
};
($span:expr, $($msg:tt)*) => { c_bail!($span => $($msg)*) }
}

View File

@ -6,19 +6,18 @@ extern crate proc_macro2;
use proc_macro::TokenStream;
#[macro_use]
mod error;
mod util;
mod api_def;
mod parsing;
mod types;
mod util;
mod api_macro;
mod router_macro;
fn handle_error(kind: &'static str, err: failure::Error) -> TokenStream {
match err.downcast::<error::CompileError>() {
Ok(err) => err.tokens,
match err.downcast::<syn::Error>() {
Ok(err) => err.to_compile_error().into(),
Err(err) => panic!("error in {}: {}", kind, err),
}
}

View File

@ -287,7 +287,7 @@ pub fn parse_object(tokens: TokenStream) -> Result<Object, Error> {
let value = parse_object_value(&mut tokens, &key)?;
if out.insert(key.clone(), value).is_some() {
c_bail!(key.span() => "duplicate entry: {}", key.as_str());
c_bail!(key.span(), "duplicate entry: {}", key.as_str());
}
}
@ -313,7 +313,7 @@ fn parse_object_value(tokens: &mut TokenIter, key: &Name) -> Result<Expression,
Some(token) => token,
None => {
if first {
c_bail!(key.span(), "missing value after key '{}'", key.as_str());
c_bail!(key => "missing value after key '{}'", key.as_str());
}
break;
}

View File

@ -1,3 +1,19 @@
use proc_macro2::Ident;
use syn::Token;
use syn::parse::{Parse, ParseStream};
use syn::punctuated::Punctuated;
macro_rules! c_format_err {
($span:expr => $($msg:tt)*) => { syn::Error::new_spanned($span, format!($($msg)*)) };
($span:expr, $($msg:tt)*) => { syn::Error::new($span, format!($($msg)*)) };
}
macro_rules! c_bail {
($span:expr => $($msg:tt)*) => { return Err(c_format_err!($span => $($msg)*).into()) };
($span:expr, $($msg:tt)*) => { return Err(c_format_err!($span, $($msg)*).into()) };
}
/// Convert `this_kind_of_text` to `ThisKindOfText`.
pub fn to_camel_case(text: &str) -> String {
let mut out = String::new();