#proc-macro #quote #tokens #dylib #fork #rustc #remove

standalone-quote

Fork of quote that allows disabling the proc-macro feature in proc-macro2 so as to remove the rustc dylib dependency

2 个不稳定版本

使用旧的 Rust 2015

0.5.0 2018年3月5日
0.4.2 2018年2月21日

#1938 in Rust 模式

Download history 25/week @ 2024-04-06 27/week @ 2024-04-13 24/week @ 2024-04-20 28/week @ 2024-04-27 23/week @ 2024-05-04 29/week @ 2024-05-11 23/week @ 2024-05-18 30/week @ 2024-05-25 23/week @ 2024-06-01 26/week @ 2024-06-08 29/week @ 2024-06-15 28/week @ 2024-06-22 60/week @ 2024-06-29 14/week @ 2024-07-06 32/week @ 2024-07-13 15/week @ 2024-07-20

124 个月下载量
3 个crate中使用了(通过 standalone-syn

MIT/Apache

35KB
480

Rust 近似引用

Build Status Latest Version Rust Documentation

此crate提供了将 Rust 语法树数据结构转换为源代码标记的宏 quote!

Rust 的过程宏接收一个标记流作为输入,执行任意 Rust 代码以确定如何操作这些标记,并生成一个标记流返回给编译器以编译成调用者的 crate。近似引用是解决这个问题的一部分——产生返回给编译器的标记。

近似引用的想法是我们编写将视为 数据代码。在 quote! 宏内部,我们可以编写看起来像代码的内容,就像我们的文本编辑器或 IDE 中的内容。我们得到编辑器括号匹配、语法高亮、缩进和可能的自动完成的全部好处。但是,我们不是将其作为代码编译到当前 crate 中,而是将其作为数据处理,传递它,修改它,最终将其作为标记返回给编译器以编译到宏调用者的 crate 中。

此crate由过程宏使用案例激发,但是一个通用的 Rust 近似引用库,并不特定于过程宏。

版本要求:Quote 支持 Rust 1.15.0 中对过程宏的第一个支持以来的任何编译器版本。

[dependencies]
quote = "0.4"
#[macro_use]
extern crate quote;

语法

quote crate提供了一个 quote! 宏,在其中可以编写 Rust 代码,这些代码被打包成一个 quote::Tokens 并可以作为数据处理。你应该将 Tokens 视为一个 Rust 源代码片段的表示。在 Tokens 上调用 to_string() 以将源代码片段作为字符串返回,或在过程宏中调用 into() 以将它们作为 TokenStream 流式传输回编译器。

quote!宏中,插值是通过#var来完成的。任何实现了quote::ToTokens特质的类型都可以进行插值。这包括大多数Rust基本类型以及syn中的大多数语法树类型。

let tokens = quote! {
    struct SerializeWith #generics #where_clause {
        value: &'a #field_ty,
        phantom: ::std::marker::PhantomData<#item_ty>,
    }

    impl #generics serde::Serialize for SerializeWith #generics #where_clause {
        fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
            where S: serde::Serializer
        {
            #path(self.value, s)
        }
    }

    SerializeWith {
        value: #value,
        phantom: ::std::marker::PhantomData::<#item_ty>,
    }
};

重复

重复操作使用#(...)*#(...),*,类似于macro_rules!。这遍历重复内插值的任何变量的元素,并为每个元素插入重复体副本。插值中的变量可以是任何实现了IntoIterator的类型,包括Vec或现有的迭代器。

  • #(#var)* —— 无分隔符
  • #(#var),* —— 星号前的字符用作分隔符
  • #( struct #var; )* —— 重复可以包含其他内容
  • #( #k => println!("{}", #v), )* —— 甚至可以有多重插值

注意,#(#var ,)*#(#var),*之间有区别——后者不会产生尾随逗号。这符合macro_rules!中定界符的行为。

hygiene

任何插值令牌都保留了其ToTokens实现提供的Span信息。在quote!调用中起源的令牌使用Span::def_site()进行跨域。

可以通过quote_spanned!宏显式提供不同的跨域。

递归限制

《quote!》宏依赖于深度递归,因此在编译时,某些大型的调用可能会因“达到递归限制”而失败。如果失败,请通过在您的crate中添加以下代码来增加递归限制:#![recursion_limit = "128"]。对于特别大的调用,可能需要更高的限制。除非编译器告诉您需要这样做,否则不需要这样做。

许可证

根据您的选择,许可方式如下:

贡献

除非您明确表示,否则根据Apache-2.0许可证定义的,您有意提交的任何贡献,都应按照上述方式双重许可,不附加任何额外条款或条件。

依赖

~225KB