use proc_macro2::{Span, TokenStream};
use syn::{Error, Expr, ExprLit, Lit, LitInt, LitStr, Token, parse_quote};
use syn::parse::{Parse, ParseStream};
use syn::punctuated::Punctuated;
pub struct DceError {
code: Expr,
formatter: LitStr,
args: Punctuated<Expr, Token![,]>
}
impl DceError {
pub fn gen_func(self, public: bool) -> TokenStream {
let DceError{code, formatter, args} = self;
parse_quote!(dce_util::result::DceError::msg(#public, #code, format!(#formatter, #args)))
}
}
impl Parse for DceError {
fn parse(input: ParseStream) -> syn::Result<Self> {
let (code, formatter) = match input.parse() {
Ok(expr @ (Expr::Path(_) | Expr::Lit(ExprLit { lit: Lit::Int(_), .. }))) if input.parse::<Token![,]>().is_ok() && ! input.is_empty() => (
expr,
if let Ok(Expr::Lit(ExprLit { lit: Lit::Str(formatter), .. })) = input.parse() { formatter } else { unreachable!() }
),
Ok(Expr::Lit(ExprLit { lit: Lit::Str(formatter), .. })) => (
Expr::Lit(ExprLit{ attrs: vec![], lit: Lit::Int(LitInt::new("0", Span::call_site())) }),
formatter
),
_ => panic!("{}", Error::new(Span::call_site(), "Must special a valid message")),
};
let _ = input.parse::<Token![,]>();
Ok(DceError{ code, formatter, args: Punctuated::parse_terminated(input)? })
}
}