学习Rust编程——派生宏

学习Rust编程——派生宏extern crate proc_macro;use proc_macro::TokenStream;use quote::quote;use

欢迎大家来到IT世界,在知识的湖畔探索吧!


extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, Data, DeriveInput, Fields};

#[proc_macro_derive(IntoMap)]
pub fn into_map_derive(input: TokenStream) -> TokenStream {
    let mut insert_tokens = vec![];
    let parsed_input: DeriveInput = parse_macro_input!(input);
    let struct_name = parsed_input.ident;
    match parsed_input.data {
        Data::Struct(s) => {
            if let Fields::Named(named_fields) = s.fields {
                let fields = named_fields.named;
                for f in fields {
                    let field = f.ident.unwrap();
                    let insert_token = quote! {
                        map.insert(
                            stringify!(#field).to_string(),
                            self.#field.to_string()
                        );
                    };
                    insert_tokens.push(insert_token);
                }
            }
        }
        other => panic!("IntoMap is not yet implemented for: {:?}", other),
    }

    let tokens = quote! {
        use std::collections::BTreeMap;
        use into_map::IntoMap;

        impl IntoMap for #struct_name {
            /// Converts the given struct into a dynamic map
            fn into_map(&self) -> BTreeMap<String, String> {
                let mut map = BTreeMap::new();
                #(#insert_tokens)*
                map
            }
        }
    };

    proc_macro::TokenStream::from(tokens)
}

欢迎大家来到IT世界,在知识的湖畔探索吧!

欢迎大家来到IT世界,在知识的湖畔探索吧![lib]
proc-macro = true

[dependencies]
syn = { version = "0.15", features = ["extra-traits"] }
quote = "0.6"
into_map = { path="../into_map" }
// into_map_demo/into_map/src/lib.rs

use std::collections::BTreeMap;

pub trait IntoMap {
    fn into_map(&self) -> BTreeMap<String, String>;
}
欢迎大家来到IT世界,在知识的湖畔探索吧!// into_map_demo/src/main.rs

use into_map_derive::IntoMap;

#[derive(IntoMap)]
struct User {
    name: String,
    id: usize,
    active: bool
}

fn main() {
    let my_bar = User { name: "Alice".to_string(), id: 35, active: false };
    let map = my_bar.into_map();
    println!("{:?}", map);
}
[dependencies]
into_map = { path = "into_map" }
into_map_derive = { path = "into_map_derive" }

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/34321.html

(0)
上一篇 2023年 11月 30日 上午8:23
下一篇 2023年 12月 3日 下午7:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信