Darling
1. 名词解释
field (字段)是指属于一个对象或数据结构的一个数据成员,在宏编程时我们往往期望获得字段的名词、字段的类型、以及额外的自定义属性
2. 使用原因
期望在过程宏中解析syn::DeriveInput
得出申明性属性。
例1: 结构体中的 field ---> bar 中的 skip 属性为 true
#[derive(Lorem)]
pub struct Foo {
#[lorem(skip)]
bar: bool,
baz: i64,
}
例2: 结构体本身具有一个属性 field 为 inner
#[allow(unused)]
#[derive(Debug, AutoDeref)]
#[deref(field = "inner")]
pub struct RespBulkString {
inner: String,
nothing: (),
}
3. 使用 Darling 的一般姿势,以 极客时间Rust auto_deref 为例
为结构体 RespBulkString 自动实现
#[allow(unused)]
#[derive(Debug, AutoDeref)]
#[deref(field = "inner")]
pub struct RespBulkString {
inner: String,
nothing: (),
}
为结构体 RespBulkString 自动实现
impl std::ops::Deref for RespBulkString {
type Target = String;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl std::ops::DerefMut for RespBulkString {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
3.1 在 lib.rs 中对外暴露 AutoDeref
#[proc_macro_derive(AutoDeref, attributes(deref))]
pub fn derive_auto_deref(input: TokenStream) -> TokenStream {
let input = syn::parse_macro_input!(input as DeriveInput);
println!("{:#?}", input);
process_auto_deref(input).into()
}
3.2 编写转换函数 process_auto_deref
// 参数为 DeriveInput
pub(crate) fn process_auto_deref(input: DeriveInput) -> TokenStream {
}
3.3 定义 AutoDeref 的结构体
// 使用 FromDeriveInput 宏自动实现 FromDeriveInput
// AutoDeref 拥有函数 fn from_derive_input(input: &DeriveInput) -> Result<Self, Error>,用于解析 syn::DeriveInput
#[derive(Debug, FromDeriveInput)]
#[darling(attributes(deref))]
struct AutoDeref {
ident: syn::Ident,
generics: syn::Generics,
// Data 为 enum,前者代表使用 AutoRef 宏的是 enum 类型 —— 与事实不符
// 后者代表使用 AutoRef 宏的是 struct 类型
data: Data<(), AutoDerefField>,
#[darling(default)]
field: Option<syn::Ident>,
#[darling(default)]
mutable: bool,
}
3.4 定义 AutoDerefField,AutoDeref 中的 data 对应多个 AutoDerefField
#[derive(Debug, FromField)]
struct AutoDerefField {
ident: Option<syn::Ident>,
ty: syn::Type,
}
4. 拓展
#[derive(Lorem)]
pub struct Foo {
#[lorem(skip)]
bar: bool,
baz: i64,
}
当中的 attributes 同样适用于struct 中的 field 官方示例
#[derive(Debug, FromField)]
#[darling(attributes(lorem))]
pub struct LoremField {
ident: Option<Ident>,
ty: Type,
#[darling(default)]
skip: bool,
}
#[derive(Debug, FromDeriveInput)]
#[darling(attributes(lorem), supports(struct_named))]
pub struct Lorem {
ident: Ident,
data: ast::Data<util::Ignored, LoremField>,
}
标签:derive,struct,pub,一库,input,deref,Darling,AutoDeref,Rust
From: https://www.cnblogs.com/wyzwsy/p/18202863