macro: add spanned format_err equivalent

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
Wolfgang Bumiller 2019-07-18 10:47:41 +02:00
parent 145abf62a5
commit 9654d1feeb
2 changed files with 18 additions and 9 deletions

View File

@ -17,9 +17,10 @@ pub fn api_macro(attr: TokenStream, item: TokenStream) -> Result<TokenStream, Er
let definition = match definition { let definition = match definition {
TokenTree::Group(ref group) if group.delimiter() == Delimiter::Brace => group.stream(), TokenTree::Group(ref group) if group.delimiter() == Delimiter::Brace => group.stream(),
_ => cbail!(definition.span() => "expected api definition in braces"), _ => c_bail!(definition.span() => "expected api definition in braces"),
}; };
let def_span = definition.span();
let definition = parse_object(definition)?; let definition = parse_object(definition)?;
// Now parse the item, based on which we decide whether this is an API method which needs a // Now parse the item, based on which we decide whether this is an API method which needs a
@ -33,17 +34,18 @@ pub fn api_macro(attr: TokenStream, item: TokenStream) -> Result<TokenStream, Er
output.extend(extra); output.extend(extra);
Ok(output) Ok(output)
} }
syn::Item::Fn(func) => handle_function(definition, func), syn::Item::Fn(func) => handle_function(def_span, definition, func),
_ => cbail!(item.span() => "api macro currently only applies to structs and functions"), _ => c_bail!(item.span() => "api macro currently only applies to structs and functions"),
} }
} }
fn handle_function( fn handle_function(
def_span: Span,
mut definition: HashMap<String, Expression>, mut definition: HashMap<String, Expression>,
mut item: syn::ItemFn, mut item: syn::ItemFn,
) -> Result<TokenStream, Error> { ) -> Result<TokenStream, Error> {
if item.decl.generics.lt_token.is_some() { if item.decl.generics.lt_token.is_some() {
cbail!( c_bail!(
item.decl.generics.span(), item.decl.generics.span(),
"cannot use generic functions for api macros currently", "cannot use generic functions for api macros currently",
); );
@ -56,7 +58,7 @@ fn handle_function(
let fn_api_description = definition let fn_api_description = definition
.remove("description") .remove("description")
.ok_or_else(|| format_err!("missing 'description' in method definition"))? .ok_or_else(|| c_format_err!(def_span, "missing 'description' in method definition"))?
.expect_lit_str()?; .expect_lit_str()?;
let fn_api_protected = definition let fn_api_protected = definition

View File

@ -14,11 +14,18 @@ impl std::fmt::Display for CompileError {
impl std::error::Error for CompileError {} impl std::error::Error for CompileError {}
macro_rules! cbail { macro_rules! c_format_err {
($span:expr => $($msg:tt)*) => { ($span:expr => $($msg:tt)*) => {
return Err(::failure::Error::from(crate::error::CompileError { crate::error::CompileError {
tokens: ::quote::quote_spanned! { $span => compile_error!($($msg)*); }.into() tokens: ::quote::quote_spanned! { $span => compile_error!($($msg)*); }.into()
})) }
}; };
($span:expr, $($msg:tt)*) => { cbail!($span => $($msg)*) } ($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)*) }
} }