1# synstructure 2 3[](https://crates.io/crates/synstructure) 4[](https://docs.rs/synstructure) 5[](https://travis-ci.org/mystor/synstructure) 6[](https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html) 7 8> NOTE: What follows is an exerpt from the module level documentation. For full 9> details read the docs on [docs.rs](https://docs.rs/synstructure/) 10 11This crate provides helper types for matching against enum variants, and 12extracting bindings to each of the fields in the deriving Struct or Enum in 13a generic way. 14 15If you are writing a `#[derive]` which needs to perform some operation on 16every field, then you have come to the right place! 17 18# Example: `WalkFields` 19### Trait Implementation 20```rust 21pub trait WalkFields: std::any::Any { 22 fn walk_fields(&self, walk: &mut FnMut(&WalkFields)); 23} 24impl WalkFields for i32 { 25 fn walk_fields(&self, _walk: &mut FnMut(&WalkFields)) {} 26} 27``` 28 29### Custom Derive 30```rust 31#[macro_use] 32extern crate synstructure; 33#[macro_use] 34extern crate quote; 35extern crate proc_macro2; 36 37fn walkfields_derive(s: synstructure::Structure) -> proc_macro2::TokenStream { 38 let body = s.each(|bi| quote!{ 39 walk(#bi) 40 }); 41 42 s.bound_impl(quote!(example_traits::WalkFields), quote!{ 43 fn walk_fields(&self, walk: &mut FnMut(&example_traits::WalkFields)) { 44 match *self { #body } 45 } 46 }) 47} 48decl_derive!([WalkFields] => walkfields_derive); 49 50/* 51 * Test Case 52 */ 53fn main() { 54 test_derive! { 55 walkfields_derive { 56 enum A<T> { 57 B(i32, T), 58 C(i32), 59 } 60 } 61 expands to { 62 const _: () = { 63 extern crate example_traits; 64 impl<T> example_traits::WalkFields for A<T> 65 where T: example_traits::WalkFields 66 { 67 fn walk_fields(&self, walk: &mut FnMut(&example_traits::WalkFields)) { 68 match *self { 69 A::B(ref __binding_0, ref __binding_1,) => { 70 { walk(__binding_0) } 71 { walk(__binding_1) } 72 } 73 A::C(ref __binding_0,) => { 74 { walk(__binding_0) } 75 } 76 } 77 } 78 } 79 }; 80 } 81 } 82} 83``` 84 85# Example: `Interest` 86### Trait Implementation 87```rust 88pub trait Interest { 89 fn interesting(&self) -> bool; 90} 91impl Interest for i32 { 92 fn interesting(&self) -> bool { *self > 0 } 93} 94``` 95 96### Custom Derive 97```rust 98#[macro_use] 99extern crate synstructure; 100#[macro_use] 101extern crate quote; 102extern crate proc_macro2; 103 104fn interest_derive(mut s: synstructure::Structure) -> proc_macro2::TokenStream { 105 let body = s.fold(false, |acc, bi| quote!{ 106 #acc || example_traits::Interest::interesting(#bi) 107 }); 108 109 s.bound_impl(quote!(example_traits::Interest), quote!{ 110 fn interesting(&self) -> bool { 111 match *self { 112 #body 113 } 114 } 115 }) 116} 117decl_derive!([Interest] => interest_derive); 118 119/* 120 * Test Case 121 */ 122fn main() { 123 test_derive!{ 124 interest_derive { 125 enum A<T> { 126 B(i32, T), 127 C(i32), 128 } 129 } 130 expands to { 131 const _: () = { 132 extern crate example_traits; 133 impl<T> example_traits::Interest for A<T> 134 where T: example_traits::Interest 135 { 136 fn interesting(&self) -> bool { 137 match *self { 138 A::B(ref __binding_0, ref __binding_1,) => { 139 false || 140 example_traits::Interest::interesting(__binding_0) || 141 example_traits::Interest::interesting(__binding_1) 142 } 143 A::C(ref __binding_0,) => { 144 false || 145 example_traits::Interest::interesting(__binding_0) 146 } 147 } 148 } 149 } 150 }; 151 } 152 } 153} 154``` 155 156For more example usage, consider investigating the `abomonation_derive` crate, 157which makes use of this crate, and is fairly simple. 158