Skip to main content

vacro_parser_macro/
lib.rs

1use proc_macro::TokenStream;
2use vacro_doc_i18n::doc_i18n;
3
4use crate::impls::{bind_impl, define_impl};
5
6pub(crate) mod ast;
7pub(crate) mod codegen;
8mod impls;
9pub(crate) mod scope_context;
10pub(crate) mod syntax;
11pub(crate) mod transform;
12mod utils;
13
14#[doc_i18n]
15/// @cn 即时解析宏:在现有的解析逻辑中快速消费 `TokenStream`
16/// @en On-the-fly parsing macro: Quickly consume a `TokenStream` within existing parsing logic
17///
18/// ::: @cn
19///
20/// `bind!` 宏模拟了一个 `let` 绑定语句。其中的核心部分 `(<input> -> <pattern>)` 会被展开为一个表达式,
21/// 其求值结果为 `syn::Result<Output>`。
22///
23/// 这意味着你可以像处理普通 `Result` 一样处理它,例如在后面直接接 `?` 操作符、`.unwrap()` 或者 `.map(...)`。
24///
25/// # 语法
26///
27/// ```text
28/// vacro::bind!(let <绑定模式> = (<输入流> -> <Vacro模式>) <后续操作>);
29/// ```
30///
31/// * **绑定模式**: 标准 Rust 模式,用于接收解析成功后的内容(如变量名 `res` 或元组 `(a, b)`)。
32/// * **输入流**: 实现了 `Into<TokenStream>` 的变量。
33/// * **Vacro模式**: 描述语法的模式。
34/// * **后续操作**: 针对 `Result` 的操作,如 `?;`、`.unwrap();` 等。
35///
36/// # 捕获规则
37///
38/// * **具名捕获** (`#(name: Type)`): 宏会生成一个包含这些字段的临时结构体 `Output`。
39/// * **行内捕获** (`#(@: Type)`): 宏会返回一个元组(或单个值),按照定义的顺序包含捕获的内容。
40///
41/// # 示例
42///
43/// ```rust
44/// # use syn::{Ident, Type, Token, Result};
45/// # use vacro_parser::bind;
46/// # use proc_macro2::TokenStream;
47/// fn parser(input: TokenStream) -> Result<()> {
48///     // 场景 1: 配合 `?` 使用 (推荐)
49///     // 表达式 `(input -> ...)` 返回 Result,后面接 `?` 传播错误
50///     let input1 = input.clone();
51///     bind!(
52///         let func = (input1 -> fn #(name: Ident))?;
53///     );
54///     println!("Function: {}", func.name);
55///
56///     // 场景 2: 配合 `unwrap` 使用
57///     // 如果你确定这里一定能解析成功
58///     let input2 = input.clone();
59///     bind!(
60///         let (arrow, ty) = (input2 -> #(@: Token![->]) #(@: Type)).unwrap();
61///     );
62///
63///     // 场景 3: 手动处理 Result
64///     let input3 = input.clone();
65///     bind!(
66///         let result = (input3 -> #(kw: Token![mod]));
67///     );
68///     if let Ok(output) = result {
69///         // ...
70///     }
71///
72///     Ok(())
73/// }
74/// ```
75/// :::
76/// ::: @en
77///
78/// The `bind!` macro mimics a `let` binding statement. The core expression `(<input> -> <pattern>)`
79/// expands to a block that evaluates to `syn::Result<Output>`.
80///
81/// This means you can treat it like any other `Result` expression, appending `?`, `.unwrap()`,
82/// or `.map(...)` directly after it.
83///
84/// # Syntax
85///
86/// ```text
87/// vacro::bind!(let <binding> = (<input> -> <pattern>) <operations>);
88/// ```
89///
90/// * **binding**: Standard Rust pattern to receive the parsed content (e.g., `res` or `(a, b)`).
91/// * **input**: A variable implementing `Into<TokenStream>`.
92/// * **pattern**: The Vacro pattern description.
93/// * **operations**: Operations on the `Result`, such as `?;`, `.unwrap();`, etc.
94///
95/// # Capture Rules
96///
97/// * **Named Capture** (`#(name: Type)`): Generates a temporary `Output` struct containing these fields.
98/// * **Inline Capture** (`#(@: Type)`): Returns a tuple (or single value) containing captured items in order.
99///
100/// # Example
101///
102/// ```rust
103/// # use syn::{Ident, Type, Token, Result};
104/// # use vacro_parser::bind;
105/// # use quote::ToTokens;
106/// # use proc_macro2::TokenStream;
107/// fn parser(input: TokenStream) -> Result<()> {
108///     // Case 1: Using with `?` (Recommended)
109///     // The expression `(input -> ...)` returns Result, `?` propagates error
110///     let input1 = input.clone();
111///     bind!(
112///         let func = (input1 -> fn #(name: Ident))?;
113///     );
114///     println!("Function: {}", func.name);
115///
116///     // Case 2: Using with `unwrap`
117///     // If you are sure parsing will succeed
118///     let input2 = input.clone();
119///     bind!(
120///         let (arrow, ty) = (input2 -> #(@: Token![->]) #(@: Type)).unwrap();
121///     );
122///
123///     // Case 3: Manually handling Result
124///     let input3 = input.clone();
125///     bind!(
126///         let result = (input3 -> #(kw: Token![mod]));
127///     );
128///     if let Ok(output) = result {
129///         // ...
130///     }
131///
132///     Ok(())
133/// }
134/// ```
135/// :::
136#[proc_macro]
137pub fn bind(input: TokenStream) -> TokenStream {
138    bind_impl(input)
139}
140
141#[doc_i18n]
142/// @cn 结构体定义宏:定义一个新的 AST 节点并自动实现 `syn::parse::Parse`
143/// @en Struct definition macro: Define a new AST node and implement `syn::parse::Parse` automatically
144///
145/// ::: @cn
146/// `define!` 宏用于创建可复用的语法结构。它会根据提供的模式生成一个结构体,
147/// 并生成相应的解析逻辑,使其可以直接通过 `syn::parse_macro_input!` 或 `input.parse()` 使用。
148///
149/// # 语法
150///
151/// ```text
152/// vacro::define!(StructName: <Pattern>);
153/// ```
154///
155/// 宏会自动生成:
156/// 1. `struct StructName { ... }`:包含所有**具名捕获**的字段。
157/// 2. `impl syn::parse::Parse for StructName { ... }`:包含解析逻辑。
158///
159/// # 注意事项
160///
161/// * `define!` 中通常使用**具名捕获** (`#(name: Type)`) 来生成结构体字段。
162///
163/// # 示例
164///
165/// ```rust
166/// # use syn::{Ident, Type, Token, parse::Parse, parse::ParseStream, Result};
167/// # use vacro_parser::define;
168/// # use quote::quote;
169/// # use proc_macro2::TokenStream;
170/// // 定义一个简单的常量定义结构
171/// // const NAME: Type = Value;
172/// define!(MyConst:
173///     const
174///     #(name: Ident)
175///     :
176///     #(ty: Type)
177///     =
178///     #(value: syn::Expr)
179///     ;
180/// );
181///
182/// fn parser(input: ParseStream) -> Result<()> {
183///     // MyConst 自动实现了 Parse trait
184///     let MyConst { name, ty, value } = input.parse()?;
185///     println!("Const {} has type {}, value: {}", name, quote!(#ty), quote!(#value));
186///     Ok(())
187/// }
188/// ```
189///
190/// :::
191///
192/// ::: @en
193///
194/// The `define!` macro is used to create reusable syntax structures. It generates a struct
195/// based on the provided pattern and implements the parsing logic, making it usable
196/// directly via `syn::parse_macro_input!` or `input.parse()`.
197///
198/// # Syntax
199///
200/// ```text
201/// vacro::define!(StructName: <Pattern>);
202/// ```
203///
204/// The macro automatically generates:
205/// 1. `struct StructName { ... }`: Containing all **named captured** fields.
206/// 2. `impl syn::parse::Parse for StructName { ... }`: Containing the parsing logic.
207///
208/// # Notes
209///
210/// * `define!` typically uses **Named Captures** (`#(name: Type)`) to generate struct fields.
211///
212/// # Example
213///
214/// ```rust
215/// # use syn::{Ident, Type, Token, parse::Parse, parse::ParseStream, Result};
216/// # use vacro_parser::define;
217/// # use quote::quote;
218/// # use proc_macro2::TokenStream;
219/// // Define a simple constant definition structure
220/// // const NAME: Type = Value;
221/// define!(MyConst:
222///     const
223///     #(name: Ident)
224///     :
225///     #(ty: Type)
226///     =
227///     #(value: syn::Expr)
228///     ;
229/// );
230///
231/// fn parser(input: ParseStream) -> Result<()> {
232///     // MyConst automatically implements the Parse trait
233///     let MyConst { name, ty, value } = input.parse()?;
234///     println!("Const {} has type {}, value: {}", name, quote!(#ty), quote!(#value));
235///     Ok(())
236/// }
237/// ```
238///
239/// :::
240#[proc_macro]
241pub fn define(input: TokenStream) -> TokenStream {
242    define_impl(input)
243}