wd_macro 0.4.1

wd macro for rust
Documentation
extern crate proc_macro;

use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, ItemStruct};

pub fn global(_: TokenStream, item: TokenStream) -> TokenStream {
    let input = parse_macro_input!(item as ItemStruct);

    let get_function = format!("__get_static_var_{}", input.ident.to_string());
    let struct_name = input.ident.to_string();
    let static_var = generate_static_var(struct_name.as_str(), get_function.as_str());
    let struct_name = proc_macro2::Ident::new(struct_name.as_str(), proc_macro2::Span::call_site());
    let get_function =
        proc_macro2::Ident::new(get_function.as_str(), proc_macro2::Span::call_site());
    let tokens = quote! {
        #static_var
        #input
        wd_tools::share!(#struct_name,#get_function);
    };

    TokenStream::from(tokens)
}

fn generate_static_var(struct_name: &str, get_function: &str) -> proc_macro2::TokenStream {
    let static_global_struct_var = format!("__SGSV_{}", struct_name);
    let static_global_struct_var = proc_macro2::Ident::new(
        static_global_struct_var.as_str(),
        proc_macro2::Span::call_site(),
    );
    let static_global_once_var = format!("__SGOV_{}", struct_name);
    let static_global_once_var = proc_macro2::Ident::new(
        static_global_once_var.as_str(),
        proc_macro2::Span::call_site(),
    );
    let get_function = proc_macro2::Ident::new(get_function, proc_macro2::Span::call_site());
    let panic_info = format!("{struct_name} init failed");
    let struct_name = proc_macro2::Ident::new(struct_name, proc_macro2::Span::call_site());
    let ts = quote! {
    static mut #static_global_struct_var:Option<wd_tools::sync::AsyncMutex<#struct_name>> =  None;
    static mut #static_global_once_var:std::sync::Once = std::sync::Once::new();

    fn #get_function() -> &'static wd_tools::sync::AsyncMutex<#struct_name> {
        unsafe {
            #static_global_once_var.call_once(||{
                #static_global_struct_var = Some(wd_tools::sync::AsyncMutex::new(std::default::Default::default()))
            });
            match #static_global_struct_var {
                Some(ref s) => {
                    s
                }
                None => {
                    panic!(#panic_info)
                }
            }
        }
    }
        };
    ts
}