18 releases

0.3.5 May 3, 2024
0.3.4 May 3, 2024
0.3.2 Apr 27, 2024
0.2.9 Mar 31, 2024
0.1.1 Feb 16, 2024

#1811 in Procedural macros

Download history 17/week @ 2024-07-22 66/week @ 2024-07-29 33/week @ 2024-08-05 27/week @ 2024-08-12 22/week @ 2024-08-19 65/week @ 2024-08-26 22/week @ 2024-09-02 18/week @ 2024-09-09 26/week @ 2024-09-16 54/week @ 2024-09-23 15/week @ 2024-09-30 2/week @ 2024-10-07 18/week @ 2024-10-14 21/week @ 2024-10-21 11/week @ 2024-10-28 21/week @ 2024-11-04

71 downloads per month
Used in 13 crates (2 directly)

MIT license

40KB
999 lines

描述

用于rust过程宏开发辅助工具包

使用

派生宏 GetTokenStream

用于生成获取改类型值的token stream,如:

    #[test]
    fn test_token_stream() {
        #[derive(GetTokenStream)]
        pub enum Ass {
            S(Student),
        }

        #[derive(GetTokenStream)]
        pub struct Student {
            pub name: String,
            pub age: i32,
        }
        let student = Student {
            name: "lloyd".to_string(),
            age: 18,
        };

        let a = Ass::S(student);
        println!("{}", a.get_token_stream());
    }

输出结果为: Ass :: S (Student { name : "lloyd" . into () , age : 18i32 , } ,)

派生宏 MetaParser

用于解析宏辅助参数,将参数元数据解析为特定的枚举

  • 指定解析的参数名称使用[name]进行标注
  • 元组项的类型没有实现parse stream时,可使用[converter]进行转换
  • 带名的结构体使用类型的FromMetaExpr实现,调用try_from_expr方法进行获取 如:
    #[test]
    fn test_meta_parser() {
        #[derive(MetaParser)]
        enum Context {
            #[name("note")]
            Note(#[converter(LitStr)] String),

            #[name("note")]
            NoteNameSize { name: LitStr, size: LitInt },

            #[name("note")]
            NoteName { name: LitStr },
        }

        let input: ItemStruct = parse_quote! {
            #[note("111")]
            #[note(name = "222", size = 18)]
            #[note(name = "333")]
            pub struct MyStruct {
                pub name: String,
            }
        };
        let attrs = input.attrs;
        for attr in attrs {
            let context = Context::parse(&attr.meta);
            if let Ok(context) = context {
                match context {
                    Context::Note(name) => {
                        println!("{}", name);
                    }
                    Context::NoteNameSize { name, size } => {
                        println!(
                            "name = {}, size = {}",
                            name.value(),
                            size.base10_parse::<i64>().unwrap()
                        );
                    }
                    Context::NoteName { name } => {
                        println!("name = {}", name.value());
                    }
                }
            }
        }
    }

Dependencies

~250–690KB
~16K SLoC