#meta-programming #derive #macro-derive #meta

self-rust-tokenize

将 Rust 结构体实例转换为创建该实例的标记流

8 个版本

新版本 0.4.0 2024 年 8 月 16 日
0.3.4 2024 年 3 月 1 日
0.3.3 2023 年 2 月 1 日
0.3.2 2023 年 1 月 30 日
0.1.0 2022 年 1 月 3 日

261Rust 模式

Download history 12/week @ 2024-04-29 22/week @ 2024-05-06 47/week @ 2024-05-13 60/week @ 2024-05-20 49/week @ 2024-05-27 35/week @ 2024-06-03 27/week @ 2024-06-10 33/week @ 2024-06-17 20/week @ 2024-06-24 10/week @ 2024-07-08 54/week @ 2024-07-15 13/week @ 2024-07-22 44/week @ 2024-07-29 67/week @ 2024-08-05 192/week @ 2024-08-12

321 每月下载量
用于 8 个 crate (6 个直接使用)

MIT 许可证

18KB
279

Self Rust Tokenize

crates.io badge docs.rs badge

用于将结构体实例转换为生成结构的 proc_macro2::TokenStream 标记流。

assert_eq!(
    self_rust_tokenize::SelfRustTokenize::to_tokens(&String::from("Hello")).to_string(),
    self_rust_tokenize::helpers::quote!(::std::string::String::from("Hello")).to_string()
);

在自定义类型上推导

#[derive(self_rust_tokenize::SelfRustTokenize)]
struct A(pub i32);

let a = A(12);
assert_eq!(
    self_rust_tokenize::SelfRustTokenize::to_tokens(&a).to_string(),
    self_rust_tokenize::helpers::quote!(A(12i32,)).to_string()
);

用例可能包括:在处理结构体实例的 crate 和生成导出 proc macro 中构建实例的 proc macro crate 之间共享结构体。

它可以用于对由于结构体性质而分配的结构体进行常量编译。 (此 crate 是为了部分常量编译抽象语法树而构建的)

/// Base definition crate
pub struct SpecialStructure { 
    // ...
}

impl SpecialStructure {
    pub fn generate_from_input(&str) -> Self {
        // some long implementation
    }
}

/// Proc macro crate
use base_crate::SpecialStructure; 

#[proc_macro]
pub fn make_special_structure(item: TokenStream) -> TokenStream {
    let input = parse_macro_input!(item as LitStr).value();
    let instance = SpecialStructure::generate_from_input(&input);
    let instance_constructor = instance.to_tokens();
    quote! {
        {
            use ::base_crate::SpecialStructure;
            #instance_constructor
        }
    }.into()
}

/// Main crate
SpecialStructure::generate_from_input("hello") == make_special_structure!("hello")

请注意,推导出的标记流没有作用域,您必须导入结构体本身

Cargo 功能

  • smallvec,在 smallvec crate 中添加了 SelfRustTokenize 的实现
  • references,添加了不可变和可变引用以及不可变和可变切片的 SelfRustTokenize 实现。请注意,对于引用,标记化不会保留结构,因为在新结构的标记化中指针信息不同。例如,ptr::eq 的行为将不同。(因此,这是可选功能的原因)

为什么使用 self_rust_tokenize::SelfRustTokenize 特性而不是 quote::ToTokens

quote::ToTokens 在 std 中的许多类型上定义,以返回它们更原始的表示形式,并且可能会丢失它们的类型结构。另一方面,self_rust_tokenize::SelfRustTokenize 在 std 类型上的实现保留了类型构造信息。因此,需要一个新特性(self_rust_tokenize::SelfRustTokenize)来防止实现冲突。

例如:

let hello_string = String::new("Hello");
self_rust_tokenize::SelfRustTokenize::to_tokens(hello_string) == quote!(::std::string::String::new("Hello"));
quote::ToTokens::to_tokens(hello_string) == quote!("Hello");

依赖关系

~0.4–0.8MB
~20K SLoC