2 个不稳定版本
使用旧的 Rust 2015
0.5.0 | 2018年3月5日 |
---|---|
0.4.2 | 2018年2月21日 |
#1938 in Rust 模式
124 个月下载量
在 3 个crate中使用了(通过 standalone-syn)
35KB
480 行
Rust 近似引用
此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 License,版本2.0(LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT许可证(LICENSE-MIT 或 http://opensource.org/licenses/MIT)
。
贡献
除非您明确表示,否则根据Apache-2.0许可证定义的,您有意提交的任何贡献,都应按照上述方式双重许可,不附加任何额外条款或条件。
依赖
~225KB