#syn #quote #macro #parse-input #reverse #pattern #parse-stream

过程宏 unquote

一个反向引号宏...也就是说,一个从给定模式中解析ParseStream输入的宏。

3次发布

0.0.7 2023年8月26日
0.0.6 2020年12月4日
0.0.5 2020年11月13日

过程宏 中排名 2028

每月下载量 46
2 个Crate中使用(通过 fruit-salad_proc-macro-de…

MIT/Apache

15KB
155

unquote

Lib.rs Crates.io Docs.rs

Rust 1.45.0 CI Crates.io - License

GitHub open issues open pull requests crev reviews

一个反向引号宏...也就是说,一个从 ParseStream 按照给定模式解析输入的宏。

注意:此库仍在开发中。虽然我不期望语法会有大的破坏性变化,但还有一些功能缺失,并且错误消息还不总是很好。

此宏当前需要当前命名空间中可用 syn,并且至少启用了 "extra-traits""parsing" 功能。这将在下一次较大的重构中得到修复。

安装

请使用 cargo-edit 来始终添加此库的最新版本

cargo add unquote

示例

use call2_for_syn::call2_strict;
use quote::quote;
use std::error::Error;
use syn::{LitStr, parse::ParseStream};
use unquote::unquote;

fn main() -> Result<(), Box<dyn Error>> {
  // Sample input
  let tokens = quote!(<!-- "Hello!" -->);

  // Analogous to a parser implementation with `syn`:
  fn parser_function(input: ParseStream) -> syn::Result<LitStr> {
    // Declare bindings ahead of time.
    // Rust can usually infer the type.
    let parsed;

    // This uses the ? operator internally -
    // It needs to be inside a `Result`-returning function.
    unquote!(input, <!-- #parsed -->);

    Ok(parsed)
  }

  let parsed = call2_strict(tokens, parser_function)??;
  assert_eq!(parsed.value(), "Hello!");
  Ok(())
}

实现状态

(按优先级顺序大致排列)

标记
标点 🗸³
标识符
文字
绑定
#绑定
#let绑定
#do解析函数=>绑定
#do let解析函数=>绑定
##-转义
()
{}
[]
可变参数¹
#(#绑定)?
#(#绑定)*
#(#绑定),*
#(#绑定)+²
#(#绑定),+²
跨度捕获
#'span
#^'span
#$'span
位置绑定...?⁵
#0
实用宏
Unquotable-derive⁶
辅助函数
关键字
AnyIdent

¹ 注意,所有可变参数在第一个TokenTree之后都是急切的,并且只进行非常浅的推测性解析!在实践中,这意味着例如将++解析为#(+-)?++将会失败,因为第一个+ "锁定"了可选短语。

² 在quote中并不特别存在,但需要可变参数非常好。

³ 目前没有区分如=>= >之类的组合。这最终会改变,同时伴随着破坏性语义版本号变化。

⁴ 将Span作为生命周期表示有点不寻常,但可以用不同的颜色很好地突出显示它们。

⁵ 当在例如if let条件中使用宏时,这会很有用(因为位置绑定只会在宏表达式的结果中以值的形式返回),并且不会干扰命名绑定。这确实是一个额外的功能,如果确实可以干净地添加的话。

⁶ 这应该适用于struct并且实现syn::Parse和一个检查第一个标记的自定义特质。

许可证

根据您的选择,许可协议为

贡献

除非您明确说明,否则您提交给作品以包含在内的任何贡献,根据Apache-2.0许可证定义,应按上述方式双重许可,不附加任何额外条款或条件。

行为准则

变更日志

版本控制

unquote严格遵循语义版本化2.0.0,有以下例外

  • 次要版本在主要版本更改时不会重置为0(除了v1)。
    将其视为全局功能级别。
  • 补丁版本在主要或次要版本更改时不会重置为0(除了v0.1和v1)。
    将其视为全局补丁级别。

这包括上述指定的Rust版本要求。
早期Rust版本可能兼容,但这可能会随着次要或补丁版本而改变。

受功能和补丁影响的版本可以通过CHANGELOG.md中相应的标题确定。

依赖项

~285–730KB
~17K SLoC