27次发布

0.13.1 2024年1月30日
0.13.0 2023年3月24日
0.12.6 2021年10月9日
0.12.5 2021年7月11日
0.4.0 2016年11月16日

#7 in 过程宏

Download history 457123/week @ 2024-04-22 432410/week @ 2024-04-29 414840/week @ 2024-05-06 480594/week @ 2024-05-13 492374/week @ 2024-05-20 480552/week @ 2024-05-27 500196/week @ 2024-06-03 993755/week @ 2024-06-10 793305/week @ 2024-06-17 679359/week @ 2024-06-24 537849/week @ 2024-07-01 584313/week @ 2024-07-08 599113/week @ 2024-07-15 619489/week @ 2024-07-22 596539/week @ 2024-07-29 624549/week @ 2024-08-05

2,473,876 每月下载量
用于 4,015 个Crate(114个直接使用)

MIT 许可证

99KB
1K SLoC

synstructure

Latest Version Documentation Build Status Rustc Version 1.31+

注意:以下内容是模块级文档的摘录。要获取完整详细信息,请阅读docs.rs上的文档。

此Crate提供辅助类型以匹配枚举变体,并以通用方式提取派生Struct或Enum中每个字段的绑定。

如果您正在编写需要在对每个字段执行某些操作的#[derive],那么您就来到了正确的位置!

示例:WalkFields

特质实现

pub trait WalkFields: std::any::Any {
    fn walk_fields(&self, walk: &mut FnMut(&WalkFields));
}
impl WalkFields for i32 {
    fn walk_fields(&self, _walk: &mut FnMut(&WalkFields)) {}
}

自定义派生

#[macro_use]
extern crate synstructure;
#[macro_use]
extern crate quote;
extern crate proc_macro2;

fn walkfields_derive(s: synstructure::Structure) -> proc_macro2::TokenStream {
    let body = s.each(|bi| quote!{
        walk(#bi)
    });

    s.bound_impl(quote!(example_traits::WalkFields), quote!{
        fn walk_fields(&self, walk: &mut FnMut(&example_traits::WalkFields)) {
            match *self { #body }
        }
    })
}
decl_derive!([WalkFields] => walkfields_derive);

/*
 * Test Case
 */
fn main() {
    test_derive! {
        walkfields_derive {
            enum A<T> {
                B(i32, T),
                C(i32),
            }
        }
        expands to {
            const _: () = {
                extern crate example_traits;
                impl<T> example_traits::WalkFields for A<T>
                    where T: example_traits::WalkFields
                {
                    fn walk_fields(&self, walk: &mut FnMut(&example_traits::WalkFields)) {
                        match *self {
                            A::B(ref __binding_0, ref __binding_1,) => {
                                { walk(__binding_0) }
                                { walk(__binding_1) }
                            }
                            A::C(ref __binding_0,) => {
                                { walk(__binding_0) }
                            }
                        }
                    }
                }
            };
        }
    }
}

示例:Interest

特质实现

pub trait Interest {
    fn interesting(&self) -> bool;
}
impl Interest for i32 {
    fn interesting(&self) -> bool { *self > 0 }
}

自定义派生

#[macro_use]
extern crate synstructure;
#[macro_use]
extern crate quote;
extern crate proc_macro2;

fn interest_derive(mut s: synstructure::Structure) -> proc_macro2::TokenStream {
    let body = s.fold(false, |acc, bi| quote!{
        #acc || example_traits::Interest::interesting(#bi)
    });

    s.bound_impl(quote!(example_traits::Interest), quote!{
        fn interesting(&self) -> bool {
            match *self {
                #body
            }
        }
    })
}
decl_derive!([Interest] => interest_derive);

/*
 * Test Case
 */
fn main() {
    test_derive!{
        interest_derive {
            enum A<T> {
                B(i32, T),
                C(i32),
            }
        }
        expands to {
            const _: () = {
                extern crate example_traits;
                impl<T> example_traits::Interest for A<T>
                    where T: example_traits::Interest
                {
                    fn interesting(&self) -> bool {
                        match *self {
                            A::B(ref __binding_0, ref __binding_1,) => {
                                false ||
                                    example_traits::Interest::interesting(__binding_0) ||
                                    example_traits::Interest::interesting(__binding_1)
                            }
                            A::C(ref __binding_0,) => {
                                false ||
                                    example_traits::Interest::interesting(__binding_0)
                            }
                        }
                    }
                }
            };
        }
    }
}

有关更多示例用法,请考虑调查abomonation_derive crate,该crate使用了此crate,并且相当简单。

依赖项

~255–700KB
~17K SLoC