botx_api_framework_codegen/
lib.rs

1use proc_macro::TokenStream;
2use quote::format_ident;
3use syn::{*, parse::Parser};
4
5#[proc_macro_attribute]
6pub fn button_data(args: TokenStream, input: TokenStream) -> TokenStream {
7    let mut item_struct = parse_macro_input!(input as ItemStruct);
8    let _ = parse_macro_input!(args as parse::Nothing);
9    
10    let name = item_struct.ident.clone();
11
12    let method_name = format_ident!("get_type_id_{}", name.to_string());
13    let method_name_str = method_name.to_string();
14
15    let custom_type_id_name = format_ident!("{}TypeId", name.to_string());
16
17    if let syn::Fields::Named(ref mut fields) = item_struct.fields {
18        let mut field = syn::Field::parse_named
19            .parse2(quote::quote! { pub type_id: #custom_type_id_name })
20            .unwrap();
21
22        fields.named.push(field);
23    }
24
25    return quote::quote! {
26        #[derive(serde::Serialize, serde::Deserialize)]
27        #item_struct
28
29        #[derive(serde::Serialize, serde::Deserialize)]
30        pub struct #custom_type_id_name (pub String);
31
32        impl Default for #custom_type_id_name {
33            fn default() -> Self {
34                Self(std::any::type_name::<#name>().to_string())
35            }
36        }
37
38        impl Into<serde_json::Value> for #name {
39            fn into(self) -> serde_json::Value {
40                serde_json::to_value(self).unwrap()
41            }
42        }
43    }
44    .into();
45}