当前位置:网站首页>Rust procedure macro simply imitates Lombok function

Rust procedure macro simply imitates Lombok function

2022-06-24 08:34:00 8 pineapple

Concept

Use JDK8 When developing applications , Often used Lombok Some annotation functions in , For example, use @Data To generate class members Get/Set Method .

Try using today Rust To implement similar functions .

practice

technological process :

  1. Use Syn In the library parse_macro_input analysis DeriveInput
  2. Traverse the target object Fields Domain
  3. Use format_ident! Splice generation function name
  4. Use quote In the library quote! Generate TokenStream paragraph
  5. Generate the target impl Method

A little more complicated quote Subsegment , Attach to master lombok_data_fun The process of .

Let's take an example :

// lib.rs
#[proc_macro_derive(Data)]
pub fn lombok_data(input: TokenStream)->TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    let data = input.data;

    let mut lombok_data_fun= quote! { };
    match data {
        Data::Struct(s)=>{
            //  Traversal members 
            for f in s.fields{
                let attr_name = f.ident.to_token_stream();
                let attr_ty = f.ty.to_token_stream();
				//  Splice function name 
                let get_name =  format_ident!("get_{}", attr_name.to_string());
                let set_name =  format_ident!("set_{}", attr_name.to_string());
                let t = quote! {
                    pub fn #get_name(&self)->&#attr_ty{
                        &self.#attr_name
                    }
                    pub fn #set_name(&mut self, val:#attr_ty){
                        self.#attr_name = val
                    }
                };
				//  Sub segments are spliced into main segments 
                lombok_data_fun = quote! {
                    #lombok_data_fun 
                    #t
                }
            }
        },
        _=>()
    }
	//  Get structure name 
    let name = input.ident.to_token_stream();
    let  expanded = quote! {
        impl #name {
            #lombok_data_fun
        }
    };
    expanded.into()

}


// main.rs
#[derive(Data)]
struct LombokTest {
    name: String,
    age : i32,
}

fn main() {

    let mut test = LombokTest {
        name: "Baby".to_string(),
        age: 10,
    };
    test.set_name(" Zhang San ".to_string());
    println!("{}", test.get_name());
}
原网站

版权声明
本文为[8 pineapple]所创,转载请带上原文链接,感谢
https://yzsam.com/2021/06/20210623184250462G.html