1 个不稳定版本

0.1.0 2019年8月25日

#1814过程宏

Download history 657/week @ 2024-03-13 461/week @ 2024-03-20 687/week @ 2024-03-27 348/week @ 2024-04-03 451/week @ 2024-04-10 318/week @ 2024-04-17 415/week @ 2024-04-24 344/week @ 2024-05-01 319/week @ 2024-05-08 510/week @ 2024-05-15 772/week @ 2024-05-22 454/week @ 2024-05-29 471/week @ 2024-06-05 543/week @ 2024-06-12 462/week @ 2024-06-19 450/week @ 2024-06-26

2,056 每月下载量
3 crate 中使用(2 个直接使用)

MIT 许可证

47KB
868 代码行数(不含注释)

Build Status Documentation

serde_syn

serde_syn 是一个用于在过程宏内部解析 Rust 语法的 serde 后端。例如,您可以将自定义 derive 的参数从属性直接解析到结构体中。目标是消除编写过程宏时所需的解析样板代码。

serde_syn 的接口相当简单。以下是一些使用方法

  • syn 需要 Parser 实现来处理已解析/访问过的 attributes 内部的语法。函数 parser 正好可以做到这一点!
  • 如果您正在直接处理 proc_macro/proc_macro2 标记流或字符串,也应使用 parser
  • 如果您正在自己实现 syn 的 Parse trait,则应使用 from_stream 函数,它接受一个 ParseStream

config 模块内部存在许多针对常见语法(如 JSON 类似、属性类似、表达式类似等)的预先配置,或者您可以组合标志来构建自己的配置。

示例 derive 实现

在这里,您可以看到一个简单的 derive 宏实现。更多示例,请参阅 示例目录

#
#
/// The format of `named` attributes.
#[derive(Deserialize)]
struct Props {
    rename: Option<String>, // #[named(rename="hello")]
    lowercase: Option<()>,  // #[named(lowercase)]
}

#[proc_macro_derive(NamedType, attributes(named))]
pub fn my_macro(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as DeriveInput);
    let mut name = input.ident.to_string();

    for attr in input.attrs.iter().filter(|a| a.path.is_ident("named")) {
        let parser = parser::<Props>(config::RUSTY_META);
        let props = match attr.parse_args_with(parser) {
            Ok(props) => props,
            Err(err) => return err.to_compile_error().into(),
        };

        if let Some(rename) = props.rename { name = rename; }
        if props.lowercase.is_some() { name = name.to_lowercase(); }
    }

    let ident = &input.ident;
    (quote! {
        impl NamedType for #ident {
            fn name() -> &'static str { #name }
        }
    }).into()
}

错误处理

反序列化错误在从parserfrom_stream返回之前,会自动分配一个"span"(无法解析的源代码区域),然后以普通syn::Error的形式返回。当该错误报告给Rust编译器时,正确的代码区域将被突出显示

error: unknown field `lowrcase`, expected `rename` or `lowercase`
  --> named_type.rs:4:13
   |
4  |     #[named(lowrcase)]
   |             ^^^^^^^^

如果您直接使用Deserializer,serde_syn会尽力分配一个span,但总是可以使用serde所需的custom函数创建一个没有span的错误。

限制

serde_syn处于早期开发阶段,因此仍然存在一些问题。例如,如果您尝试将数据反序列化到serde_json Value,serde_syn将会抛出一个错误,因为它还不支持自我描述。

如果您发现任何错误,有任何想法,或者有空闲时间帮助随机的开源项目,请访问存储库

依赖关系

~2MB
~43K SLoC