vacro-parser 0.1.16

A declarative parsing library for Rust procedural macros, simplifying input handling.
Documentation
# Vacro Parser

**Vacro 的声明式解析内核**

## 简介

**Vacro Parser** 是 Vacro 框架的核心声明式解析引擎。它提供了一种类似 `macro_rules!` 的 DSL,用于简化 Rust 过程宏中基于 `syn` 的解析逻辑。

它允许你声明式地定义 AST 结构和解析逻辑,消除了繁琐的 `input.parse()?` 调用。

## 核心功能

### 1. `define!`:定义解析结构体

使用 `define!` 定义一个结构体,它会自动实现 `syn::parse::Parse`。

```rust
# use syn::{Ident, Type, GenericParam, FnArg, parse_quote, Token};
# use vacro_parser::define;
// 定义一个名为 MyFn 的结构体,它会自动实现 Parse trait
define!(MyFn:
    fn
    #(?: <#(generic*[,]: GenericParam)>)
    #(name: Ident)
    ( #(args*[,]: FnArg) )
    #(?: -> #(ret: Type))
);

fn parse_my_fn(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream {
    // 使用方式
    let my_fn: MyFn = parse_quote!(input);
    println!("Function name: {}", my_fn.name);
    proc_macro2::TokenStream::new()
}
# fn main() {}
```

### 2. `bind!`:即时流解析

在现有的命令式逻辑中,使用 `bind!` 快速消费一段 `TokenStream`。

```rust
# use syn::{Ident, Type, Token, Result};
# use vacro_parser::bind;
# fn parser(input: proc_macro2::TokenStream) -> Result<()> {
// 即时解析函数签名模式
bind!(
    let captured = (input ->
        fn #(name: Ident) #(?: -> #(ret: Type))
    )?;
);

// 直接访问捕获的字段
println!("Name: {}", captured.name);
if let Some(ret_type) = captured.ret {
    // ...
}
# Ok(())
# }
# fn main() {}
```

## 语法参考

| 语法                 | 描述                                       | 解析结果类型          | 示例                                                                  |
| :------------------- | :----------------------------------------- | :-------------------- | :-------------------------------------------------------------------- |
| `literal`            | 匹配并消费确切的 Token                     | `!`                   | `fn`, `->`, `struct`                                                  |
| `#(x: T)`            | **具名捕获**: 捕获类型 `T` 到字段 `x`      | `T`                   | `#(name: Ident)`                                                      |
| `#(x?: T)`           | **具名可选**: 尝试解析,失败则跳过         | `Option<T>`           | `#(ret?: Type)`                                                       |
| `#(x*: T)`           | **具名空白迭代**: 连续解析 token           | `Vec<T>`              | `#(tokens*: Ident)`                                                   |
| `#(x*[]: T)`         | **具名空白迭代**: 连续解析 token           | `Vec<T>`              | `#(tokens*[]: Ident)`                                                 |
| `#(x*[sep]: T)`      | **具名分隔迭代**: 按分隔符解析             | `Punctuated<T, sep>`  | `#(args*[,]: FnArg)`                                                  |
| `#(x..)`             | **具名收集**: 收集直到当前作用域结束       | `TokenStream`         | `#(rest..)`                                                           |
| `#(x?..)`            | **具名可选收集**: 可选地收集剩余 token     | `Option<TokenStream>` | `#(prefix?..)`                                                        |
| `#(x..[stop])`       | **具名终止收集**: 收集直到终止符并消费它   | `TokenStream`         | `#(prefix..[:])`                                                      |
| `#(x?..[stop])`      | **具名可选终止收集**: 终止符不存在则跳过   | `Option<TokenStream>` | `#(prefix?..[:])`                                                     |
| `#(x.. \| #(...))`   | **具名后继收集**: 收集直到后继捕获匹配     | `TokenStream`         | `#(token.. \| #(mode: OptionMode { Spaced: #{:}, Assigned: #{=} }))`  |
| `#(x?.. \| #(...))`  | **具名可选后继收集**: 后继捕获不存在则跳过 | `Option<TokenStream>` | `#(token?.. \| #(mode: OptionMode { Spaced: #{:}, Assigned: #{=} }))` |
| `#(T)`               | **匿名捕获**: 验证 `T` 存在但不捕获        | `!`                   | `#(Ident)`                                                            |
| `#(?: T)`            | **匿名可选**: 仅作验证                     | `!`                   | `#(?: Ident)`                                                         |
| `#(*: #(x: T))`      | **匿名嵌套空白迭代**: 汇总内部字段         | `Vec<T>`              | `#(*: #(name: Ident))`                                                |
| `#(*[sep]: #(x: T))` | **匿名嵌套分隔迭代**: 汇总内部字段         | `Punctuated<T, sep>`  | `#(*[,]: #(name: Ident))`                                             |
| `#{literal}`         | **字面量捕获**: 按内容的字面量进行捕获     | `!`                   | `#{ #(not: a #(capture)) }`                                           |

## 多态捕获 (Enum Parsing)

Vacro 支持解析“多态”结构,即输入流中的某个位置可能是多种类型之一。

```rust
# use syn::{Ident, Expr, Type, LitInt};
# use vacro_parser::define;
define!(MyPoly:
    #(data: MyEnum {
        Ident,                            // 1. 简写:匹配 Ident,生成 MyEnum::Ident(Ident)
        syn::Type,                        // 2. 简写:匹配 Type,生成 MyEnum::Type(syn::Type)
        Integer: syn::LitInt,             // 3. 别名:匹配 LitInt,生成 MyEnum::Integer(LitInt)
        Function: fn #(name: Ident),      // 4. 模式:生成 MyEnum::Function { name: Ident }
        Tuple: (#(@: Ident), #(@: Expr)), // 5. 模式:生成 MyEnum::Tuple(Ident, Expr)
    })
);
# fn main() {}
```

## 更友好的提示 (v0.1.6)

你可以使用`vacro-report`的`help!`宏为内容提供更友好的提示,若你使用了`vacro`,只需要开启`report`feature即可。

```toml
vacro_parser = { version = "0.1.16" }
vacro_report = { version = "0.1.3", features = ["parser"] }

# vacro = { version = "0.2.11", features = ["parser", "report"] }
```

```rust,ignore
use vacro_parser::define;
use vacro_report::help;
# use syn::{Ident, LitBool};

help!(Bool:
    LitBool {
        error: "此处需要一个bool字面量,接收到的是:{input}",
        help: "尝试`true`或`false`",
        example: (true | false) // example 字段是要展示的示例字段,在生成错误信息与使用示例时使用;它接受一段TokenStream,并且将直接展示你传入的内容
    }
);

define!(MyRoles: {
    #(roles*[,]: #(pair: #(name: syn::Ident): #(enable: Bool)))
});

```