removed standard_framework completely
This commit is contained in:
@ -8,12 +8,7 @@ extern crate proc_macro;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{
|
||||
parse::Error,
|
||||
parse_macro_input, parse_quote,
|
||||
spanned::Spanned,
|
||||
Lit,
|
||||
};
|
||||
use syn::{parse::Error, parse_macro_input, spanned::Spanned, Lit};
|
||||
|
||||
pub(crate) mod attributes;
|
||||
pub(crate) mod consts;
|
||||
@ -74,15 +69,9 @@ pub fn command(attr: TokenStream, input: TokenStream) -> TokenStream {
|
||||
can_blacklist,
|
||||
} = options;
|
||||
|
||||
propagate_err!(create_declaration_validations(&mut fun, DeclarFor::Command));
|
||||
|
||||
let res = parse_quote!(serenity::framework::standard::CommandResult);
|
||||
create_return_type_validation(&mut fun, res);
|
||||
|
||||
let visibility = fun.visibility;
|
||||
let name = fun.name.clone();
|
||||
let body = fun.body;
|
||||
let ret = fun.ret;
|
||||
|
||||
let n = name.with_suffix(COMMAND);
|
||||
|
||||
@ -103,7 +92,7 @@ pub fn command(attr: TokenStream, input: TokenStream) -> TokenStream {
|
||||
can_blacklist: #can_blacklist,
|
||||
};
|
||||
|
||||
#visibility fn #name<'fut> (#(#args),*) -> ::serenity::futures::future::BoxFuture<'fut, #ret> {
|
||||
#visibility fn #name<'fut> (#(#args),*) -> ::serenity::futures::future::BoxFuture<'fut, ()> {
|
||||
use ::serenity::futures::future::FutureExt;
|
||||
|
||||
async move { #(#body)* }.boxed()
|
||||
|
@ -6,8 +6,7 @@ use syn::{
|
||||
braced,
|
||||
parse::{Error, Parse, ParseStream, Result},
|
||||
spanned::Spanned,
|
||||
Attribute, Block, FnArg, Ident, Pat, Path, PathSegment, ReturnType, Stmt,
|
||||
Token, Type, Visibility,
|
||||
Attribute, Block, FnArg, Ident, Pat, Path, PathSegment, Stmt, Token, Visibility,
|
||||
};
|
||||
|
||||
fn parse_argument(arg: FnArg) -> Result<Argument> {
|
||||
@ -54,15 +53,7 @@ fn parse_argument(arg: FnArg) -> Result<Argument> {
|
||||
/// Test if the attribute is cooked.
|
||||
fn is_cooked(attr: &Attribute) -> bool {
|
||||
const COOKED_ATTRIBUTE_NAMES: &[&str] = &[
|
||||
"cfg",
|
||||
"cfg_attr",
|
||||
"doc",
|
||||
"derive",
|
||||
"inline",
|
||||
"allow",
|
||||
"warn",
|
||||
"deny",
|
||||
"forbid",
|
||||
"cfg", "cfg_attr", "doc", "derive", "inline", "allow", "warn", "deny", "forbid",
|
||||
];
|
||||
|
||||
COOKED_ATTRIBUTE_NAMES.iter().any(|n| attr.path.is_ident(n))
|
||||
@ -100,7 +91,6 @@ pub struct CommandFun {
|
||||
pub visibility: Visibility,
|
||||
pub name: Ident,
|
||||
pub args: Vec<Argument>,
|
||||
pub ret: Type,
|
||||
pub body: Vec<Stmt>,
|
||||
}
|
||||
|
||||
@ -131,14 +121,6 @@ impl Parse for CommandFun {
|
||||
// (...)
|
||||
let Parenthesised(args) = input.parse::<Parenthesised<FnArg>>()?;
|
||||
|
||||
let ret = match input.parse::<ReturnType>()? {
|
||||
ReturnType::Type(_, t) => (*t).clone(),
|
||||
ReturnType::Default => {
|
||||
return Err(input
|
||||
.error("expected a result type of either `CommandResult` or `CheckResult`"))
|
||||
}
|
||||
};
|
||||
|
||||
// { ... }
|
||||
let bcont;
|
||||
braced!(bcont in input);
|
||||
@ -155,7 +137,6 @@ impl Parse for CommandFun {
|
||||
visibility,
|
||||
name,
|
||||
args,
|
||||
ret,
|
||||
body,
|
||||
})
|
||||
}
|
||||
@ -169,13 +150,12 @@ impl ToTokens for CommandFun {
|
||||
visibility,
|
||||
name,
|
||||
args,
|
||||
ret,
|
||||
body,
|
||||
} = self;
|
||||
|
||||
stream.extend(quote! {
|
||||
#(#cooked)*
|
||||
#visibility async fn #name (#(#args),*) -> #ret {
|
||||
#visibility async fn #name (#(#args),*) -> () {
|
||||
#(#body)*
|
||||
}
|
||||
});
|
||||
|
@ -1,4 +1,3 @@
|
||||
use crate::structures::CommandFun;
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::Span;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
@ -6,9 +5,7 @@ use quote::{format_ident, quote, ToTokens};
|
||||
use syn::{
|
||||
braced, bracketed, parenthesized,
|
||||
parse::{Error, Parse, ParseStream, Result as SynResult},
|
||||
parse_quote,
|
||||
punctuated::Punctuated,
|
||||
spanned::Spanned,
|
||||
token::{Comma, Mut},
|
||||
Ident, Lifetime, Lit, Type,
|
||||
};
|
||||
@ -153,83 +150,6 @@ impl ToTokens for Argument {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn generate_type_validation(have: Type, expect: Type) -> syn::Stmt {
|
||||
parse_quote! {
|
||||
serenity::static_assertions::assert_type_eq_all!(#have, #expect);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum DeclarFor {
|
||||
Command,
|
||||
Help,
|
||||
Check,
|
||||
}
|
||||
|
||||
pub fn create_declaration_validations(fun: &mut CommandFun, dec_for: DeclarFor) -> SynResult<()> {
|
||||
let len = match dec_for {
|
||||
DeclarFor::Command => 3,
|
||||
DeclarFor::Help => 6,
|
||||
DeclarFor::Check => 4,
|
||||
};
|
||||
|
||||
if fun.args.len() > len {
|
||||
return Err(Error::new(
|
||||
fun.args.last().unwrap().span(),
|
||||
format_args!("function's arity exceeds more than {} arguments", len),
|
||||
));
|
||||
}
|
||||
|
||||
let context: Type = parse_quote!(&serenity::client::Context);
|
||||
let message: Type = parse_quote!(&serenity::model::channel::Message);
|
||||
let args: Type = parse_quote!(String);
|
||||
let options: Type = parse_quote!(&serenity::framework::standard::CommandOptions);
|
||||
let hoptions: Type = parse_quote!(&'static serenity::framework::standard::HelpOptions);
|
||||
let groups: Type = parse_quote!(&[&'static serenity::framework::standard::CommandGroup]);
|
||||
let owners: Type = parse_quote!(std::collections::HashSet<serenity::model::id::UserId>);
|
||||
|
||||
let mut index = 0;
|
||||
|
||||
let mut spoof_or_check = |kind: Type, name: &str| {
|
||||
match fun.args.get(index) {
|
||||
Some(x) => fun.body.insert(0, generate_type_validation(x.kind.clone(), kind)),
|
||||
None => fun.args.push(Argument {
|
||||
mutable: None,
|
||||
name: Ident::new(name, Span::call_site()),
|
||||
kind,
|
||||
}),
|
||||
}
|
||||
|
||||
index += 1;
|
||||
};
|
||||
|
||||
spoof_or_check(context, "_ctx");
|
||||
spoof_or_check(message, "_msg");
|
||||
|
||||
if dec_for == DeclarFor::Check {
|
||||
spoof_or_check(options, "_options");
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
spoof_or_check(args, "_args");
|
||||
|
||||
if dec_for == DeclarFor::Help {
|
||||
spoof_or_check(hoptions, "_hoptions");
|
||||
spoof_or_check(groups, "_groups");
|
||||
spoof_or_check(owners, "_owners");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn create_return_type_validation(r#fn: &mut CommandFun, expect: Type) {
|
||||
let stmt = generate_type_validation(r#fn.ret.clone(), expect);
|
||||
r#fn.body.insert(0, stmt);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn populate_fut_lifetimes_on_refs(args: &mut Vec<Argument>) {
|
||||
for arg in args {
|
||||
|
Reference in New Issue
Block a user