Rust Syn/Quote宏生成JSON Schema时Where子句及泛型调用问题
解决Rust属性宏
myschema处理带Where子句泛型函数的问题 错误1:no rules expected the token :
这个错误是因为宏解析逻辑没正确处理带Where子句的泛型函数签名。Syn解析时遇到Where子句里的类型约束冒号(比如T: std::ops::Mul<Output = T>)时,找不到匹配的解析规则——大概率是之前只解析了函数签名的部分字段,没完整捕获包含where子句的generics结构。
解决方法:用Syn的ItemFn完整解析输入函数,它会自动处理泛型参数和Where子句。
错误2:生成的辅助函数无泛型参数
生成的schema_multiply没继承原函数的泛型参数和Where子句,导致调用时传入<i32>出现参数不匹配。这是因为生成代码时没把原函数的泛型信息传递到辅助函数定义里。
完整修复代码示例
use proc_macro::TokenStream; use quote::quote; use syn::{parse_macro_input, ItemFn}; #[proc_macro_attribute] pub fn myschema(_attr: TokenStream, input: TokenStream) -> TokenStream { // 完整解析输入函数,包含泛型、Where子句等所有信息 let func: ItemFn = parse_macro_input!(input); let name = &func.sig.ident; let schema_name = format_ident!("schema_{}", name); let return_type = &func.sig.output; // 捕获原函数的泛型参数和Where子句 let generics = &func.generics; let expanded = quote! { // 保留原函数定义 #func #[allow(non_snake_case)] // 将泛型参数和Where子句直接复制到辅助函数定义中 pub fn #schema_name #generics() -> schemars::schema::RootSchema { // 生成Schema时带上泛型参数,确保类型解析正确 schemars::schema_for!(#return_type #generics) } }; expanded.into() }
验证修复效果
对于带Where子句的泛型函数:
#[myschema] fn multiply<T>(a: T, b: T) -> T where T: std::ops::Mul<Output = T> + schemars::JsonSchema { a * b }
现在生成的schema_multiply会带有完整的泛型参数和Where子句,调用schema_multiply::<i32>()时不会再出现参数不匹配的错误,同时宏解析也能正确处理Where子句中的冒号。
内容的提问来源于stack exchange,提问作者richinex
相关产品推荐
相关产品推荐

