diff options
Diffstat (limited to 'third_party/rust/synstructure/README.md')
-rw-r--r-- | third_party/rust/synstructure/README.md | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/third_party/rust/synstructure/README.md b/third_party/rust/synstructure/README.md new file mode 100644 index 0000000000..b72b7bd9d5 --- /dev/null +++ b/third_party/rust/synstructure/README.md @@ -0,0 +1,159 @@ +# synstructure + +[![Latest Version](https://img.shields.io/crates/v/synstructure.svg)](https://crates.io/crates/synstructure) +[![Documentation](https://docs.rs/synstructure/badge.svg)](https://docs.rs/synstructure) +[![Build Status](https://travis-ci.org/mystor/synstructure.svg?branch=master)](https://travis-ci.org/mystor/synstructure) +[![Rustc Version 1.31+](https://img.shields.io/badge/rustc-1.31+-lightgray.svg)](https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html) + +> NOTE: What follows is an exerpt from the module level documentation. For full +> details read the docs on [docs.rs](https://docs.rs/synstructure/) + +This crate provides helper types for matching against enum variants, and +extracting bindings to each of the fields in the deriving Struct or Enum in +a generic way. + +If you are writing a `#[derive]` which needs to perform some operation on +every field, then you have come to the right place! + +# Example: `WalkFields` +### Trait Implementation +```rust +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)) {} +} +``` + +### Custom Derive +```rust +#[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 { + #[allow(non_upper_case_globals)] + const _DERIVE_example_traits_WalkFields_FOR_A: () = { + 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) } + } + } + } + } + }; + } + } +} +``` + +# Example: `Interest` +### Trait Implementation +```rust +pub trait Interest { + fn interesting(&self) -> bool; +} +impl Interest for i32 { + fn interesting(&self) -> bool { *self > 0 } +} +``` + +### Custom Derive +```rust +#[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 { + #[allow(non_upper_case_globals)] + const _DERIVE_example_traits_Interest_FOR_A: () = { + 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) + } + } + } + } + }; + } + } +} +``` + +For more example usage, consider investigating the `abomonation_derive` crate, +which makes use of this crate, and is fairly simple. |