Skip to content

Commit

Permalink
feat: enhance proc_macro derive_mania_event
Browse files Browse the repository at this point in the history
  • Loading branch information
pk5ls20 committed Feb 8, 2025
1 parent d28f0b8 commit c17f799
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 40 deletions.
76 changes: 66 additions & 10 deletions mania-macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#![feature(let_chains)]
use md5::{Digest, Md5};
use proc_macro::TokenStream;
use proc_macro2::Span;
use proc_macro2::{Ident, Span};
use quote::quote;
use syn::parse::Parse;
use syn::{
DeriveInput, ItemFn, ItemStruct, LitInt, LitStr, Path, Token, parse_macro_input,
Data, DeriveInput, Fields, ItemFn, ItemStruct, LitInt, LitStr, Path, Token,
parse::{Parse, ParseStream},
parse_macro_input,
punctuated::Punctuated,
};

Expand Down Expand Up @@ -162,13 +164,67 @@ pub fn handle_event(attr: TokenStream, item: TokenStream) -> TokenStream {
expanded.into()
}

// TODO: auto parse & auto impl debug
#[proc_macro_derive(ManiaEvent)]
pub fn mania_event_derive(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
let struct_name = &ast.ident;
let stream = quote! {
#[derive(Debug)]
struct ManiaEventPreferOptions {
debug: bool,
}

impl Parse for ManiaEventPreferOptions {
fn parse(input: ParseStream) -> Result<Self, syn::Error> {
let ident: Ident = input.parse()?;
Ok(ManiaEventPreferOptions {
debug: ident == "debug",
})
}
}

#[proc_macro_derive(ManiaEvent, attributes(prefer))]
pub fn derive_mania_event(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = parse_macro_input!(input as syn::DeriveInput);
let struct_name = &input.ident;

let mania_event_impl = quote! {
impl crate::event::ManiaEvent for #struct_name {}
};
stream.into()

let debug_impl = match &input.data {
Data::Struct(data_struct) => match &data_struct.fields {
Fields::Named(fields_named) => {
let field_entries: Vec<String> = fields_named
.named
.iter()
.map(|field| {
let field_name = field.ident.as_ref().unwrap().to_string();
let placeholder = field
.attrs
.iter()
.find(|attr| attr.path().is_ident("prefer"))
.and_then(|attr| attr.parse_args::<ManiaEventPreferOptions>().ok())
.map_or("{}", |opts| if opts.debug { "{:?}" } else { "{}" });
format!("{}: {}", field_name, placeholder)
})
.collect();
let fmt_string = format!("[{}] {}", struct_name, field_entries.join(" | "));
let field_accesses = fields_named.named.iter().map(|field| {
let field_ident = field.ident.as_ref().unwrap();
quote! { self.#field_ident }
});
quote! {
impl std::fmt::Debug for #struct_name {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, #fmt_string, #( #field_accesses ),* )
}
}
}
}
_ => quote! {},
},
_ => quote! {},
};

let expanded = quote! {
#mania_event_impl
#debug_impl
};
expanded.into()
}
8 changes: 1 addition & 7 deletions mania/src/event/bot/bot_online.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
use crate::event::prelude::*;
pub use mania_macros::ManiaEvent;

#[derive(ManiaEvent)]
pub struct BotOnlineEvent {
pub reason: String,
}

impl Debug for BotOnlineEvent {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "[BotOnlineEvent]: reason: {:?}", self.reason)
}
}
12 changes: 1 addition & 11 deletions mania/src/event/friend/friend_poke.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::event::prelude::*;
pub use mania_macros::ManiaEvent;

#[derive(ManiaEvent)]
pub struct FriendPokeEvent {
Expand All @@ -8,13 +8,3 @@ pub struct FriendPokeEvent {
pub suffix: String,
pub action_url: String,
}

impl Debug for FriendPokeEvent {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(
f,
"[FriendPokeEvent]: operator_uin: {} | target_uin: {} | action: {} | suffix: {} | action_url: {}",
self.operator_uin, self.target_uin, self.action, self.suffix, self.action_url
)
}
}
9 changes: 2 additions & 7 deletions mania/src/event/group/group_message.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
use crate::event::prelude::*;
use crate::message::chain::MessageChain;
pub use mania_macros::ManiaEvent;

#[derive(ManiaEvent)]
pub struct GroupMessageEvent {
#[prefer(debug)]
pub chain: MessageChain,
}

impl Debug for GroupMessageEvent {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
write!(f, "[GroupMessageEvent]: {:?}", self.chain)
}
}
5 changes: 0 additions & 5 deletions mania/src/event/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,3 @@ impl EventListener {
}
}
}

mod prelude {
pub use mania_macros::ManiaEvent;
pub use std::fmt::{Debug, Formatter, Result as FmtResult};
}
1 change: 1 addition & 0 deletions mania/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#![allow(dead_code)] // TODO: remove this after stable
#![feature(if_let_guard)]
#![feature(let_chains)]
extern crate alloc;

mod core;
pub mod entity;
Expand Down

0 comments on commit c17f799

Please sign in to comment.