mirror of
https://git.proxmox.com/git/proxmox
synced 2025-08-13 19:54:35 +00:00
macro: helpers for error handling
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
a1c8b00f17
commit
145abf62a5
@ -3,8 +3,8 @@ use std::collections::HashMap;
|
||||
use proc_macro2::{Delimiter, Ident, Span, TokenStream, TokenTree};
|
||||
|
||||
use failure::{bail, format_err, Error};
|
||||
use quote::{quote, quote_spanned, ToTokens};
|
||||
use syn::{Expr, Token};
|
||||
use quote::{quote, ToTokens};
|
||||
use syn::{spanned::Spanned, Expr, Token};
|
||||
|
||||
use super::api_def::{CommonTypeDefinition, ParameterDefinition};
|
||||
use super::parsing::*;
|
||||
@ -17,7 +17,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(),
|
||||
_ => bail!("expected api definition in braces"),
|
||||
_ => cbail!(definition.span() => "expected api definition in braces"),
|
||||
};
|
||||
|
||||
let definition = parse_object(definition)?;
|
||||
@ -34,7 +34,7 @@ pub fn api_macro(attr: TokenStream, item: TokenStream) -> Result<TokenStream, Er
|
||||
Ok(output)
|
||||
}
|
||||
syn::Item::Fn(func) => handle_function(definition, func),
|
||||
_ => bail!("api macro currently only applies to structs and functions"),
|
||||
_ => cbail!(item.span() => "api macro currently only applies to structs and functions"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,9 +43,10 @@ fn handle_function(
|
||||
mut item: syn::ItemFn,
|
||||
) -> Result<TokenStream, Error> {
|
||||
if item.decl.generics.lt_token.is_some() {
|
||||
return Ok(quote_spanned! { item.decl.generics.lt_token.unwrap().span =>
|
||||
compile_error!("cannot use generic functions for api macros currently");
|
||||
}.into());
|
||||
cbail!(
|
||||
item.decl.generics.span(),
|
||||
"cannot use generic functions for api macros currently",
|
||||
);
|
||||
// Not until we stabilize our generated representation!
|
||||
}
|
||||
|
||||
|
24
proxmox-api-macro/src/error.rs
Normal file
24
proxmox-api-macro/src/error.rs
Normal file
@ -0,0 +1,24 @@
|
||||
#[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! cbail {
|
||||
($span:expr => $($msg:tt)*) => {
|
||||
return Err(::failure::Error::from(crate::error::CompileError {
|
||||
tokens: ::quote::quote_spanned! { $span => compile_error!($($msg)*); }.into()
|
||||
}))
|
||||
};
|
||||
($span:expr, $($msg:tt)*) => { cbail!($span => $($msg)*) }
|
||||
}
|
@ -5,6 +5,9 @@ extern crate proc_macro2;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
|
||||
#[macro_use]
|
||||
mod error;
|
||||
|
||||
mod api_def;
|
||||
mod parsing;
|
||||
mod util;
|
||||
@ -12,6 +15,13 @@ 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,
|
||||
Err(err) => panic!("error in {}: {}", kind, err),
|
||||
}
|
||||
}
|
||||
|
||||
/// This is the `#[api(api definition)]` attribute for functions. An Api definition defines the
|
||||
/// parameters and return type of an API call. The function will automatically be wrapped in a
|
||||
/// function taking and returning a json `Value`, while performing validity checks on both input
|
||||
@ -44,7 +54,7 @@ mod router_macro;
|
||||
pub fn api(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
match api_macro::api_macro(attr.into(), item.into()) {
|
||||
Ok(output) => output.into(),
|
||||
Err(err) => panic!("error in api definition: {}", err),
|
||||
Err(err) => handle_error("api definition", err),
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,6 +145,6 @@ pub fn router(input: TokenStream) -> TokenStream {
|
||||
// TODO...
|
||||
match router_macro::router_macro(input.into()) {
|
||||
Ok(output) => output.into(),
|
||||
Err(err) => panic!("error in router macro: {}", err),
|
||||
Err(err) => handle_error("router", err),
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user