1 //! This crate provides helper types for matching against enum variants, and
2 //! extracting bindings to each of the fields in the deriving Struct or Enum in
3 //! a generic way.
4 //!
5 //! If you are writing a `#[derive]` which needs to perform some operation on
6 //! every field, then you have come to the right place!
7 //!
8 //! # Example: `WalkFields`
9 //! ### Trait Implementation
10 //! ```
11 //! pub trait WalkFields: std::any::Any {
12 //!     fn walk_fields(&self, walk: &mut FnMut(&WalkFields));
13 //! }
14 //! impl WalkFields for i32 {
15 //!     fn walk_fields(&self, _walk: &mut FnMut(&WalkFields)) {}
16 //! }
17 //! ```
18 //!
19 //! ### Custom Derive
20 //! ```
21 //! #[macro_use]
22 //! extern crate synstructure;
23 //! #[macro_use]
24 //! extern crate quote;
25 //! extern crate proc_macro2;
26 //!
27 //! fn walkfields_derive(s: synstructure::Structure) -> proc_macro2::TokenStream {
28 //!     let body = s.each(|bi| quote!{
29 //!         walk(#bi)
30 //!     });
31 //!
32 //!     s.gen_impl(quote! {
33 //!         extern crate synstructure_test_traits;
34 //!
35 //!         gen impl synstructure_test_traits::WalkFields for @Self {
36 //!             fn walk_fields(&self, walk: &mut FnMut(&synstructure_test_traits::WalkFields)) {
37 //!                 match *self { #body }
38 //!             }
39 //!         }
40 //!     })
41 //! }
42 //! # const _IGNORE: &'static str = stringify!(
43 //! decl_derive!([WalkFields] => walkfields_derive);
44 //! # );
45 //!
46 //! /*
47 //!  * Test Case
48 //!  */
49 //! fn main() {
50 //!     test_derive! {
51 //!         walkfields_derive {
52 //!             enum A<T> {
53 //!                 B(i32, T),
54 //!                 C(i32),
55 //!             }
56 //!         }
57 //!         expands to {
58 //!             #[allow(non_upper_case_globals)]
59 //!             const _DERIVE_synstructure_test_traits_WalkFields_FOR_A: () = {
60 //!                 extern crate synstructure_test_traits;
61 //!                 impl<T> synstructure_test_traits::WalkFields for A<T>
62 //!                     where T: synstructure_test_traits::WalkFields
63 //!                 {
64 //!                     fn walk_fields(&self, walk: &mut FnMut(&synstructure_test_traits::WalkFields)) {
65 //!                         match *self {
66 //!                             A::B(ref __binding_0, ref __binding_1,) => {
67 //!                                 { walk(__binding_0) }
68 //!                                 { walk(__binding_1) }
69 //!                             }
70 //!                             A::C(ref __binding_0,) => {
71 //!                                 { walk(__binding_0) }
72 //!                             }
73 //!                         }
74 //!                     }
75 //!                 }
76 //!             };
77 //!         }
78 //!     }
79 //! }
80 //! ```
81 //!
82 //! # Example: `Interest`
83 //! ### Trait Implementation
84 //! ```
85 //! pub trait Interest {
86 //!     fn interesting(&self) -> bool;
87 //! }
88 //! impl Interest for i32 {
89 //!     fn interesting(&self) -> bool { *self > 0 }
90 //! }
91 //! ```
92 //!
93 //! ### Custom Derive
94 //! ```
95 //! #[macro_use]
96 //! extern crate synstructure;
97 //! #[macro_use]
98 //! extern crate quote;
99 //! extern crate proc_macro2;
100 //!
101 //! fn interest_derive(mut s: synstructure::Structure) -> proc_macro2::TokenStream {
102 //!     let body = s.fold(false, |acc, bi| quote!{
103 //!         #acc || synstructure_test_traits::Interest::interesting(#bi)
104 //!     });
105 //!
106 //!     s.gen_impl(quote! {
107 //!         extern crate synstructure_test_traits;
108 //!         gen impl synstructure_test_traits::Interest for @Self {
109 //!             fn interesting(&self) -> bool {
110 //!                 match *self {
111 //!                     #body
112 //!                 }
113 //!             }
114 //!         }
115 //!     })
116 //! }
117 //! # const _IGNORE: &'static str = stringify!(
118 //! decl_derive!([Interest] => interest_derive);
119 //! # );
120 //!
121 //! /*
122 //!  * Test Case
123 //!  */
124 //! fn main() {
125 //!     test_derive!{
126 //!         interest_derive {
127 //!             enum A<T> {
128 //!                 B(i32, T),
129 //!                 C(i32),
130 //!             }
131 //!         }
132 //!         expands to {
133 //!             #[allow(non_upper_case_globals)]
134 //!             const _DERIVE_synstructure_test_traits_Interest_FOR_A: () = {
135 //!                 extern crate synstructure_test_traits;
136 //!                 impl<T> synstructure_test_traits::Interest for A<T>
137 //!                     where T: synstructure_test_traits::Interest
138 //!                 {
139 //!                     fn interesting(&self) -> bool {
140 //!                         match *self {
141 //!                             A::B(ref __binding_0, ref __binding_1,) => {
142 //!                                 false ||
143 //!                                     synstructure_test_traits::Interest::interesting(__binding_0) ||
144 //!                                     synstructure_test_traits::Interest::interesting(__binding_1)
145 //!                             }
146 //!                             A::C(ref __binding_0,) => {
147 //!                                 false ||
148 //!                                     synstructure_test_traits::Interest::interesting(__binding_0)
149 //!                             }
150 //!                         }
151 //!                     }
152 //!                 }
153 //!             };
154 //!         }
155 //!     }
156 //! }
157 //! ```
158 //!
159 //! For more example usage, consider investigating the `abomonation_derive` crate,
160 //! which makes use of this crate, and is fairly simple.
161 
162 extern crate proc_macro;
163 extern crate proc_macro2;
164 #[macro_use]
165 extern crate quote;
166 #[macro_use]
167 extern crate syn;
168 extern crate unicode_xid;
169 
170 use std::collections::HashSet;
171 
172 use syn::{
173     Generics, Ident, Attribute, Field, Fields, Expr, DeriveInput,
174     TraitBound, WhereClause, GenericParam, Data, WherePredicate,
175     TypeParamBound, Type, TypeMacro, FieldsUnnamed, FieldsNamed,
176     PredicateType, TypePath, token, punctuated,
177 };
178 use syn::visit::{self, Visit};
179 
180 // re-export the quote! macro so we can depend on it being around in our macro's
181 // implementations.
182 #[doc(hidden)]
183 pub use quote::*;
184 use proc_macro2::{TokenStream, TokenTree};
185 
186 use unicode_xid::UnicodeXID;
187 
188 use proc_macro2::Span;
189 
190 // NOTE: This module has documentation hidden, as it only exports macros (which
191 // always appear in the root of the crate) and helper methods / re-exports used
192 // in the implementation of those macros.
193 #[doc(hidden)]
194 pub mod macros;
195 
196 /// Changes how bounds are added
197 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
198 pub enum AddBounds {
199     /// Add for fields and generics
200     Both,
201     /// Fields only
202     Fields,
203     /// Generics only
204     Generics,
205     /// None
206     None,
207     #[doc(hidden)]
208     __Nonexhaustive,
209 }
210 
211 /// The type of binding to use when generating a pattern.
212 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
213 pub enum BindStyle {
214     /// `x`
215     Move,
216     /// `mut x`
217     MoveMut,
218     /// `ref x`
219     Ref,
220     /// `ref mut x`
221     RefMut,
222 }
223 
224 impl ToTokens for BindStyle {
to_tokens(&self, tokens: &mut TokenStream)225     fn to_tokens(&self, tokens: &mut TokenStream) {
226         match *self {
227             BindStyle::Move => {}
228             BindStyle::MoveMut => quote_spanned!(Span::call_site() => mut).to_tokens(tokens),
229             BindStyle::Ref => quote_spanned!(Span::call_site() => ref).to_tokens(tokens),
230             BindStyle::RefMut => quote_spanned!(Span::call_site() => ref mut).to_tokens(tokens),
231         }
232     }
233 }
234 
235 // Internal method for merging seen_generics arrays together.
generics_fuse(res: &mut Vec<bool>, new: &[bool])236 fn generics_fuse(res: &mut Vec<bool>, new: &[bool]) {
237     for (i, &flag) in new.iter().enumerate() {
238         if i == res.len() {
239             res.push(false);
240         }
241         if flag {
242             res[i] = true;
243         }
244     }
245 }
246 
247 // Internal method for extracting the set of generics which have been matched.
fetch_generics<'a>(set: &[bool], generics: &'a Generics) -> Vec<&'a Ident>248 fn fetch_generics<'a>(set: &[bool], generics: &'a Generics) -> Vec<&'a Ident> {
249     let mut tys = vec![];
250     for (&seen, param) in set.iter().zip(generics.params.iter()) {
251         if seen {
252             match *param {
253                 GenericParam::Type(ref tparam) => tys.push(&tparam.ident),
254                 _ => {}
255             }
256         }
257     }
258     tys
259 }
260 
261 // Internal method for sanitizing an identifier for hygiene purposes.
sanitize_ident(s: &str) -> Ident262 fn sanitize_ident(s: &str) -> Ident {
263     let mut res = String::with_capacity(s.len());
264     for mut c in s.chars() {
265         if ! UnicodeXID::is_xid_continue(c) { c = '_' }
266         // Deduplicate consecutive _ characters.
267         if res.ends_with('_') && c == '_' { continue }
268         res.push(c);
269     }
270     Ident::new(&res, Span::call_site())
271 }
272 
273 // Internal method to merge two Generics objects together intelligently.
merge_generics(into: &mut Generics, from: &Generics)274 fn merge_generics(into: &mut Generics, from: &Generics) {
275     // Try to add the param into `into`, and merge parmas with identical names.
276     'outer: for p in &from.params {
277         for op in &into.params {
278             match (op, p) {
279                 (&GenericParam::Type(ref otp), &GenericParam::Type(ref tp)) => {
280                     // NOTE: This is only OK because syn ignores the span for equality purposes.
281                     if otp.ident == tp.ident {
282                         panic!("Attempted to merge conflicting generic params: {} and {}", quote!{#op}, quote!{#p});
283                     }
284                 }
285                 (&GenericParam::Lifetime(ref olp), &GenericParam::Lifetime(ref lp)) => {
286                     // NOTE: This is only OK because syn ignores the span for equality purposes.
287                     if olp.lifetime == lp.lifetime {
288                         panic!("Attempted to merge conflicting generic params: {} and {}", quote!{#op}, quote!{#p});
289                     }
290                 }
291                 // We don't support merging Const parameters, because that wouldn't make much sense.
292                 _ => (),
293             }
294         }
295         into.params.push(p.clone());
296     }
297 
298     // Add any where clauses from the input generics object.
299     if let Some(ref from_clause) = from.where_clause {
300         into.make_where_clause()
301             .predicates
302             .extend(from_clause.predicates.iter().cloned());
303     }
304 }
305 
306 /// Information about a specific binding. This contains both an `Ident`
307 /// reference to the given field, and the syn `&'a Field` descriptor for that
308 /// field.
309 ///
310 /// This type supports `quote::ToTokens`, so can be directly used within the
311 /// `quote!` macro. It expands to a reference to the matched field.
312 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
313 pub struct BindingInfo<'a> {
314     /// The name which this BindingInfo will bind to.
315     pub binding: Ident,
316 
317     /// The type of binding which this BindingInfo will create.
318     pub style: BindStyle,
319 
320     field: &'a Field,
321 
322     // These are used to determine which type parameters are avaliable.
323     generics: &'a Generics,
324     seen_generics: Vec<bool>,
325 }
326 
327 impl<'a> ToTokens for BindingInfo<'a> {
to_tokens(&self, tokens: &mut TokenStream)328     fn to_tokens(&self, tokens: &mut TokenStream) {
329         self.binding.to_tokens(tokens);
330     }
331 }
332 
333 impl<'a> BindingInfo<'a> {
334     /// Returns a reference to the underlying `syn` AST node which this
335     /// `BindingInfo` references
ast(&self) -> &'a Field336     pub fn ast(&self) -> &'a Field {
337         self.field
338     }
339 
340     /// Generates the pattern fragment for this field binding.
341     ///
342     /// # Example
343     /// ```
344     /// # #[macro_use] extern crate quote;
345     /// # extern crate synstructure;
346     /// # #[macro_use] extern crate syn;
347     /// # use synstructure::*;
348     /// # fn main() {
349     /// let di: syn::DeriveInput = parse_quote! {
350     ///     enum A {
351     ///         B{ a: i32, b: i32 },
352     ///         C(u32),
353     ///     }
354     /// };
355     /// let s = Structure::new(&di);
356     ///
357     /// assert_eq!(
358     ///     s.variants()[0].bindings()[0].pat().to_string(),
359     ///     quote! {
360     ///         ref __binding_0
361     ///     }.to_string()
362     /// );
363     /// # }
364     /// ```
pat(&self) -> TokenStream365     pub fn pat(&self) -> TokenStream {
366         let BindingInfo {
367             ref binding,
368             ref style,
369             ..
370         } = *self;
371         quote!(#style #binding)
372     }
373 
374     /// Returns a list of the type parameters which are referenced in this
375     /// field's type.
376     ///
377     /// # Caveat
378     ///
379     /// If the field contains any macros in type position, all parameters will
380     /// be considered bound. This is because we cannot determine which type
381     /// parameters are bound by type macros.
382     ///
383     /// # Example
384     /// ```
385     /// # #[macro_use] extern crate quote;
386     /// # extern crate synstructure;
387     /// # #[macro_use] extern crate syn;
388     /// # extern crate proc_macro2;
389     /// # use synstructure::*;
390     /// # fn main() {
391     /// let di: syn::DeriveInput = parse_quote! {
392     ///     struct A<T, U> {
393     ///         a: Option<T>,
394     ///         b: U,
395     ///     }
396     /// };
397     /// let mut s = Structure::new(&di);
398     ///
399     /// assert_eq!(
400     ///     s.variants()[0].bindings()[0].referenced_ty_params(),
401     ///     &[&(syn::Ident::new("T", proc_macro2::Span::call_site()))]
402     /// );
403     /// # }
404     /// ```
referenced_ty_params(&self) -> Vec<&'a Ident>405     pub fn referenced_ty_params(&self) -> Vec<&'a Ident> {
406         fetch_generics(&self.seen_generics, self.generics)
407     }
408 }
409 
410 /// This type is similar to `syn`'s `Variant` type, however each of the fields
411 /// are references rather than owned. When this is used as the AST for a real
412 /// variant, this struct simply borrows the fields of the `syn::Variant`,
413 /// however this type may also be used as the sole variant for a struct.
414 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
415 pub struct VariantAst<'a> {
416     pub attrs: &'a [Attribute],
417     pub ident: &'a Ident,
418     pub fields: &'a Fields,
419     pub discriminant: &'a Option<(token::Eq, Expr)>,
420 }
421 
422 /// A wrapper around a `syn::DeriveInput`'s variant which provides utilities
423 /// for destructuring `Variant`s with `match` expressions.
424 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
425 pub struct VariantInfo<'a> {
426     pub prefix: Option<&'a Ident>,
427     bindings: Vec<BindingInfo<'a>>,
428     omitted_fields: bool,
429     ast: VariantAst<'a>,
430     generics: &'a Generics,
431 }
432 
433 /// Helper function used by the VariantInfo constructor. Walks all of the types
434 /// in `field` and returns a list of the type parameters from `ty_params` which
435 /// are referenced in the field.
get_ty_params<'a>(field: &Field, generics: &Generics) -> Vec<bool>436 fn get_ty_params<'a>(field: &Field, generics: &Generics) -> Vec<bool> {
437     // Helper type. Discovers all identifiers inside of the visited type,
438     // and calls a callback with them.
439     struct BoundTypeLocator<'a> {
440         result: Vec<bool>,
441         generics: &'a Generics,
442     }
443 
444     impl<'a> Visit<'a> for BoundTypeLocator<'a> {
445         // XXX: This also (intentionally) captures paths like T::SomeType. Is
446         // this desirable?
447         fn visit_ident(&mut self, id: &Ident) {
448             for (idx, i) in self.generics.params.iter().enumerate() {
449                 if let GenericParam::Type(ref tparam) = *i {
450                     if tparam.ident == *id {
451                         self.result[idx] = true;
452                     }
453                 }
454             }
455         }
456 
457         fn visit_type_macro(&mut self, x: &'a TypeMacro) {
458             // If we see a type_mac declaration, then we can't know what type parameters
459             // it might be binding, so we presume it binds all of them.
460             for r in &mut self.result {
461                 *r = true;
462             }
463             visit::visit_type_macro(self, x)
464         }
465     }
466 
467     let mut btl = BoundTypeLocator {
468         result: vec![false; generics.params.len()],
469         generics: generics,
470     };
471 
472     btl.visit_type(&field.ty);
473 
474     btl.result
475 }
476 
477 impl<'a> VariantInfo<'a> {
new(ast: VariantAst<'a>, prefix: Option<&'a Ident>, generics: &'a Generics) -> Self478     fn new(ast: VariantAst<'a>, prefix: Option<&'a Ident>, generics: &'a Generics) -> Self {
479         let bindings = match *ast.fields {
480             Fields::Unit => vec![],
481             Fields::Unnamed(FieldsUnnamed { unnamed: ref fields, .. }) |
482             Fields::Named(FieldsNamed { named: ref fields, .. }) => {
483                 fields.into_iter()
484                     .enumerate()
485                     .map(|(i, field)| {
486                         BindingInfo {
487                             // XXX: This has to be call_site to avoid privacy
488                             // when deriving on private fields.
489                             binding: Ident::new(
490                                 &format!("__binding_{}", i),
491                                 Span::call_site(),
492                             ),
493                             style: BindStyle::Ref,
494                             field: field,
495                             generics: generics,
496                             seen_generics: get_ty_params(field, generics),
497                         }
498                     })
499                     .collect::<Vec<_>>()
500             }
501         };
502 
503         VariantInfo {
504             prefix: prefix,
505             bindings: bindings,
506             omitted_fields: false,
507             ast: ast,
508             generics: generics,
509         }
510     }
511 
512     /// Returns a slice of the bindings in this Variant.
bindings(&self) -> &[BindingInfo<'a>]513     pub fn bindings(&self) -> &[BindingInfo<'a>] {
514         &self.bindings
515     }
516 
517     /// Returns a mut slice of the bindings in this Variant.
bindings_mut(&mut self) -> &mut [BindingInfo<'a>]518     pub fn bindings_mut(&mut self) -> &mut [BindingInfo<'a>] {
519         &mut self.bindings
520     }
521 
522     /// Returns a `VariantAst` object which contains references to the
523     /// underlying `syn` AST node which this `Variant` was created from.
ast(&self) -> VariantAst<'a>524     pub fn ast(&self) -> VariantAst<'a> {
525         self.ast
526     }
527 
528     /// True if any bindings were omitted due to a `filter` call.
omitted_bindings(&self) -> bool529     pub fn omitted_bindings(&self) -> bool {
530         self.omitted_fields
531     }
532 
533     /// Generates the match-arm pattern which could be used to match against this Variant.
534     ///
535     /// # Example
536     /// ```
537     /// # #[macro_use] extern crate quote;
538     /// # extern crate synstructure;
539     /// # #[macro_use] extern crate syn;
540     /// # use synstructure::*;
541     /// # fn main() {
542     /// let di: syn::DeriveInput = parse_quote! {
543     ///     enum A {
544     ///         B(i32, i32),
545     ///         C(u32),
546     ///     }
547     /// };
548     /// let s = Structure::new(&di);
549     ///
550     /// assert_eq!(
551     ///     s.variants()[0].pat().to_string(),
552     ///     quote!{
553     ///         A::B(ref __binding_0, ref __binding_1,)
554     ///     }.to_string()
555     /// );
556     /// # }
557     /// ```
pat(&self) -> TokenStream558     pub fn pat(&self) -> TokenStream {
559         let mut t = TokenStream::new();
560         if let Some(prefix) = self.prefix {
561             prefix.to_tokens(&mut t);
562             quote!(::).to_tokens(&mut t);
563         }
564         self.ast.ident.to_tokens(&mut t);
565         match *self.ast.fields {
566             Fields::Unit => {
567                 assert!(self.bindings.len() == 0);
568             }
569             Fields::Unnamed(..) => {
570                 token::Paren(Span::call_site()).surround(&mut t, |t| {
571                     for binding in &self.bindings {
572                         binding.pat().to_tokens(t);
573                         quote!(,).to_tokens(t);
574                     }
575                     if self.omitted_fields {
576                         quote!(..).to_tokens(t);
577                     }
578                 })
579             }
580             Fields::Named(..) => {
581                 token::Brace(Span::call_site()).surround(&mut t, |t| {
582                     for binding in &self.bindings {
583                         binding.field.ident.to_tokens(t);
584                         quote!(:).to_tokens(t);
585                         binding.pat().to_tokens(t);
586                         quote!(,).to_tokens(t);
587                     }
588                     if self.omitted_fields {
589                         quote!(..).to_tokens(t);
590                     }
591                 })
592             }
593         }
594         t
595     }
596 
597     /// Generates the token stream required to construct the current variant.
598     ///
599     /// The init array initializes each of the fields in the order they are
600     /// written in `variant.ast().fields`.
601     ///
602     /// # Example
603     /// ```
604     /// # #[macro_use] extern crate quote;
605     /// # extern crate synstructure;
606     /// # #[macro_use] extern crate syn;
607     /// # use synstructure::*;
608     /// # fn main() {
609     /// let di: syn::DeriveInput = parse_quote! {
610     ///     enum A {
611     ///         B(usize, usize),
612     ///         C{ v: usize },
613     ///     }
614     /// };
615     /// let s = Structure::new(&di);
616     ///
617     /// assert_eq!(
618     ///     s.variants()[0].construct(|_, i| quote!(#i)).to_string(),
619     ///
620     ///     quote!{
621     ///         A::B(0usize, 1usize,)
622     ///     }.to_string()
623     /// );
624     ///
625     /// assert_eq!(
626     ///     s.variants()[1].construct(|_, i| quote!(#i)).to_string(),
627     ///
628     ///     quote!{
629     ///         A::C{ v: 0usize, }
630     ///     }.to_string()
631     /// );
632     /// # }
633     /// ```
construct<F, T>(&self, mut func: F) -> TokenStream where F: FnMut(&Field, usize) -> T, T: ToTokens,634     pub fn construct<F, T>(&self, mut func: F) -> TokenStream
635     where
636         F: FnMut(&Field, usize) -> T,
637         T: ToTokens,
638     {
639         let mut t = TokenStream::new();
640         if let Some(prefix) = self.prefix {
641             quote!(#prefix ::).to_tokens(&mut t);
642         }
643         self.ast.ident.to_tokens(&mut t);
644 
645         match *self.ast.fields {
646             Fields::Unit => (),
647             Fields::Unnamed(FieldsUnnamed { ref unnamed, .. }) => {
648                 token::Paren::default().surround(&mut t, |t| {
649                     for (i, field) in unnamed.into_iter().enumerate() {
650                         func(field, i).to_tokens(t);
651                         quote!(,).to_tokens(t);
652                     }
653                 })
654             }
655             Fields::Named(FieldsNamed { ref named, .. }) => {
656                 token::Brace::default().surround(&mut t, |t| {
657                     for (i, field) in named.into_iter().enumerate() {
658                         field.ident.to_tokens(t);
659                         quote!(:).to_tokens(t);
660                         func(field, i).to_tokens(t);
661                         quote!(,).to_tokens(t);
662                     }
663                 })
664             }
665         }
666         t
667     }
668 
669     /// Runs the passed-in function once for each bound field, passing in a `BindingInfo`.
670     /// and generating a `match` arm which evaluates the returned tokens.
671     ///
672     /// This method will ignore fields which are ignored through the `filter`
673     /// method.
674     ///
675     /// # Example
676     /// ```
677     /// # #[macro_use] extern crate quote;
678     /// # extern crate synstructure;
679     /// # #[macro_use] extern crate syn;
680     /// # use synstructure::*;
681     /// # fn main() {
682     /// let di: syn::DeriveInput = parse_quote! {
683     ///     enum A {
684     ///         B(i32, i32),
685     ///         C(u32),
686     ///     }
687     /// };
688     /// let s = Structure::new(&di);
689     ///
690     /// assert_eq!(
691     ///     s.variants()[0].each(|bi| quote!(println!("{:?}", #bi))).to_string(),
692     ///
693     ///     quote!{
694     ///         A::B(ref __binding_0, ref __binding_1,) => {
695     ///             { println!("{:?}", __binding_0) }
696     ///             { println!("{:?}", __binding_1) }
697     ///         }
698     ///     }.to_string()
699     /// );
700     /// # }
701     /// ```
each<F, R>(&self, mut f: F) -> TokenStream where F: FnMut(&BindingInfo) -> R, R: ToTokens,702     pub fn each<F, R>(&self, mut f: F) -> TokenStream
703     where
704         F: FnMut(&BindingInfo) -> R,
705         R: ToTokens,
706     {
707         let pat = self.pat();
708         let mut body = TokenStream::new();
709         for binding in &self.bindings {
710             token::Brace::default().surround(&mut body, |body| {
711                 f(binding).to_tokens(body);
712             });
713         }
714         quote!(#pat => { #body })
715     }
716 
717     /// Runs the passed-in function once for each bound field, passing in the
718     /// result of the previous call, and a `BindingInfo`. generating a `match`
719     /// arm which evaluates to the resulting tokens.
720     ///
721     /// This method will ignore fields which are ignored through the `filter`
722     /// method.
723     ///
724     /// # Example
725     /// ```
726     /// # #[macro_use] extern crate quote;
727     /// # extern crate synstructure;
728     /// # #[macro_use] extern crate syn;
729     /// # use synstructure::*;
730     /// # fn main() {
731     /// let di: syn::DeriveInput = parse_quote! {
732     ///     enum A {
733     ///         B(i32, i32),
734     ///         C(u32),
735     ///     }
736     /// };
737     /// let s = Structure::new(&di);
738     ///
739     /// assert_eq!(
740     ///     s.variants()[0].fold(quote!(0), |acc, bi| quote!(#acc + #bi)).to_string(),
741     ///
742     ///     quote!{
743     ///         A::B(ref __binding_0, ref __binding_1,) => {
744     ///             0 + __binding_0 + __binding_1
745     ///         }
746     ///     }.to_string()
747     /// );
748     /// # }
749     /// ```
fold<F, I, R>(&self, init: I, mut f: F) -> TokenStream where F: FnMut(TokenStream, &BindingInfo) -> R, I: ToTokens, R: ToTokens,750     pub fn fold<F, I, R>(&self, init: I, mut f: F) -> TokenStream
751     where
752         F: FnMut(TokenStream, &BindingInfo) -> R,
753         I: ToTokens,
754         R: ToTokens,
755     {
756         let pat = self.pat();
757         let body = self.bindings.iter().fold(quote!(#init), |i, bi| {
758             let r = f(i, bi);
759             quote!(#r)
760         });
761         quote!(#pat => { #body })
762     }
763 
764     /// Filter the bindings created by this `Variant` object. This has 2 effects:
765     ///
766     /// * The bindings will no longer appear in match arms generated by methods
767     ///   on this `Variant` or its subobjects.
768     ///
769     /// * Impl blocks created with the `bound_impl` or `unsafe_bound_impl`
770     ///   method only consider type parameters referenced in the types of
771     ///   non-filtered fields.
772     ///
773     /// # Example
774     /// ```
775     /// # #[macro_use] extern crate quote;
776     /// # extern crate synstructure;
777     /// # #[macro_use] extern crate syn;
778     /// # extern crate proc_macro2;
779     /// # use synstructure::*;
780     /// # fn main() {
781     /// let di: syn::DeriveInput = parse_quote! {
782     ///     enum A {
783     ///         B{ a: i32, b: i32 },
784     ///         C{ a: u32 },
785     ///     }
786     /// };
787     /// let mut s = Structure::new(&di);
788     ///
789     /// s.variants_mut()[0].filter(|bi| {
790     ///     bi.ast().ident == Some(syn::Ident::new("b", proc_macro2::Span::call_site()))
791     /// });
792     ///
793     /// assert_eq!(
794     ///     s.each(|bi| quote!(println!("{:?}", #bi))).to_string(),
795     ///
796     ///     quote!{
797     ///         A::B{ b: ref __binding_1, .. } => {
798     ///             { println!("{:?}", __binding_1) }
799     ///         }
800     ///         A::C{ a: ref __binding_0, } => {
801     ///             { println!("{:?}", __binding_0) }
802     ///         }
803     ///     }.to_string()
804     /// );
805     /// # }
806     /// ```
filter<F>(&mut self, f: F) -> &mut Self where F: FnMut(&BindingInfo) -> bool,807     pub fn filter<F>(&mut self, f: F) -> &mut Self
808     where
809         F: FnMut(&BindingInfo) -> bool,
810     {
811         let before_len = self.bindings.len();
812         self.bindings.retain(f);
813         if self.bindings.len() != before_len {
814             self.omitted_fields = true;
815         }
816         self
817     }
818 
819     /// Remove the binding at the given index.
820     ///
821     /// # Panics
822     ///
823     /// Panics if the index is out of range.
remove_binding(&mut self, idx: usize) -> &mut Self824     pub fn remove_binding(&mut self, idx: usize) -> &mut Self {
825         self.bindings.remove(idx);
826         self.omitted_fields = true;
827         self
828     }
829 
830     /// Updates the `BindStyle` for each of the passed-in fields by calling the
831     /// passed-in function for each `BindingInfo`.
832     ///
833     /// # Example
834     /// ```
835     /// # #[macro_use] extern crate quote;
836     /// # extern crate synstructure;
837     /// # #[macro_use] extern crate syn;
838     /// # use synstructure::*;
839     /// # fn main() {
840     /// let di: syn::DeriveInput = parse_quote! {
841     ///     enum A {
842     ///         B(i32, i32),
843     ///         C(u32),
844     ///     }
845     /// };
846     /// let mut s = Structure::new(&di);
847     ///
848     /// s.variants_mut()[0].bind_with(|bi| BindStyle::RefMut);
849     ///
850     /// assert_eq!(
851     ///     s.each(|bi| quote!(println!("{:?}", #bi))).to_string(),
852     ///
853     ///     quote!{
854     ///         A::B(ref mut __binding_0, ref mut __binding_1,) => {
855     ///             { println!("{:?}", __binding_0) }
856     ///             { println!("{:?}", __binding_1) }
857     ///         }
858     ///         A::C(ref __binding_0,) => {
859     ///             { println!("{:?}", __binding_0) }
860     ///         }
861     ///     }.to_string()
862     /// );
863     /// # }
864     /// ```
bind_with<F>(&mut self, mut f: F) -> &mut Self where F: FnMut(&BindingInfo) -> BindStyle,865     pub fn bind_with<F>(&mut self, mut f: F) -> &mut Self
866     where
867         F: FnMut(&BindingInfo) -> BindStyle,
868     {
869         for binding in &mut self.bindings {
870             binding.style = f(&binding);
871         }
872         self
873     }
874 
875     /// Updates the binding name for each fo the passed-in fields by calling the
876     /// passed-in function for each `BindingInfo`.
877     ///
878     /// The function will be called with the `BindingInfo` and its index in the
879     /// enclosing variant.
880     ///
881     /// The default name is `__binding_{}` where `{}` is replaced with an
882     /// increasing number.
883     ///
884     /// # Example
885     /// ```
886     /// # #[macro_use] extern crate quote;
887     /// # extern crate synstructure;
888     /// # #[macro_use] extern crate syn;
889     /// # use synstructure::*;
890     /// # fn main() {
891     /// let di: syn::DeriveInput = parse_quote! {
892     ///     enum A {
893     ///         B{ a: i32, b: i32 },
894     ///         C{ a: u32 },
895     ///     }
896     /// };
897     /// let mut s = Structure::new(&di);
898     ///
899     /// s.variants_mut()[0].binding_name(|bi, i| bi.ident.clone().unwrap());
900     ///
901     /// assert_eq!(
902     ///     s.each(|bi| quote!(println!("{:?}", #bi))).to_string(),
903     ///
904     ///     quote!{
905     ///         A::B{ a: ref a, b: ref b, } => {
906     ///             { println!("{:?}", a) }
907     ///             { println!("{:?}", b) }
908     ///         }
909     ///         A::C{ a: ref __binding_0, } => {
910     ///             { println!("{:?}", __binding_0) }
911     ///         }
912     ///     }.to_string()
913     /// );
914     /// # }
915     /// ```
binding_name<F>(&mut self, mut f: F) -> &mut Self where F: FnMut(&Field, usize) -> Ident,916     pub fn binding_name<F>(&mut self, mut f: F) -> &mut Self
917     where
918         F: FnMut(&Field, usize) -> Ident,
919     {
920         for (it, binding) in self.bindings.iter_mut().enumerate() {
921             binding.binding = f(binding.field, it);
922         }
923         self
924     }
925 
926     /// Returns a list of the type parameters which are referenced in this
927     /// field's type.
928     ///
929     /// # Caveat
930     ///
931     /// If the field contains any macros in type position, all parameters will
932     /// be considered bound. This is because we cannot determine which type
933     /// parameters are bound by type macros.
934     ///
935     /// # Example
936     /// ```
937     /// # #[macro_use] extern crate quote;
938     /// # extern crate synstructure;
939     /// # #[macro_use] extern crate syn;
940     /// # extern crate proc_macro2;
941     /// # use synstructure::*;
942     /// # fn main() {
943     /// let di: syn::DeriveInput = parse_quote! {
944     ///     struct A<T, U> {
945     ///         a: Option<T>,
946     ///         b: U,
947     ///     }
948     /// };
949     /// let mut s = Structure::new(&di);
950     ///
951     /// assert_eq!(
952     ///     s.variants()[0].bindings()[0].referenced_ty_params(),
953     ///     &[&(syn::Ident::new("T", proc_macro2::Span::call_site()))]
954     /// );
955     /// # }
956     /// ```
referenced_ty_params(&self) -> Vec<&'a Ident>957     pub fn referenced_ty_params(&self) -> Vec<&'a Ident> {
958         let mut flags = Vec::new();
959         for binding in &self.bindings {
960             generics_fuse(&mut flags, &binding.seen_generics);
961         }
962         fetch_generics(&flags, self.generics)
963     }
964 }
965 
966 /// A wrapper around a `syn::DeriveInput` which provides utilities for creating
967 /// custom derive trait implementations.
968 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
969 pub struct Structure<'a> {
970     variants: Vec<VariantInfo<'a>>,
971     omitted_variants: bool,
972     ast: &'a DeriveInput,
973     extra_impl: Vec<GenericParam>,
974     add_bounds: AddBounds,
975 }
976 
977 impl<'a> Structure<'a> {
978     /// Create a new `Structure` with the variants and fields from the passed-in
979     /// `DeriveInput`.
new(ast: &'a DeriveInput) -> Self980     pub fn new(ast: &'a DeriveInput) -> Self {
981         let variants = match ast.data {
982             Data::Enum(ref data) => {
983                 (&data.variants).into_iter()
984                     .map(|v| {
985                         VariantInfo::new(
986                             VariantAst {
987                                 attrs: &v.attrs,
988                                 ident: &v.ident,
989                                 fields: &v.fields,
990                                 discriminant: &v.discriminant
991                             },
992                             Some(&ast.ident),
993                             &ast.generics,
994                         )
995                     })
996                     .collect::<Vec<_>>()
997             }
998             Data::Struct(ref data) => {
999                 // SAFETY NOTE: Normally putting an `Expr` in static storage
1000                 // wouldn't be safe, because it could contain `Term` objects
1001                 // which use thread-local interning. However, this static always
1002                 // contains the value `None`. Thus, it will never contain any
1003                 // unsafe values.
1004                 struct UnsafeMakeSync(Option<(token::Eq, Expr)>);
1005                 unsafe impl Sync for UnsafeMakeSync {}
1006                 static NONE_DISCRIMINANT: UnsafeMakeSync = UnsafeMakeSync(None);
1007 
1008                 vec![
1009                     VariantInfo::new(
1010                         VariantAst {
1011                             attrs: &ast.attrs,
1012                             ident: &ast.ident,
1013                             fields: &data.fields,
1014                             discriminant: &NONE_DISCRIMINANT.0,
1015                         },
1016                         None,
1017                         &ast.generics,
1018                     ),
1019                 ]
1020             }
1021             Data::Union(_) => {
1022                 panic!("synstructure does not handle untagged unions \
1023                     (https://github.com/mystor/synstructure/issues/6)");
1024             }
1025         };
1026 
1027         Structure {
1028             variants: variants,
1029             omitted_variants: false,
1030             ast: ast,
1031             extra_impl: vec![],
1032             add_bounds: AddBounds::Both,
1033         }
1034     }
1035 
1036     /// Returns a slice of the variants in this Structure.
variants(&self) -> &[VariantInfo<'a>]1037     pub fn variants(&self) -> &[VariantInfo<'a>] {
1038         &self.variants
1039     }
1040 
1041     /// Returns a mut slice of the variants in this Structure.
variants_mut(&mut self) -> &mut [VariantInfo<'a>]1042     pub fn variants_mut(&mut self) -> &mut [VariantInfo<'a>] {
1043         &mut self.variants
1044     }
1045 
1046     /// Returns a reference to the underlying `syn` AST node which this
1047     /// `Structure` was created from.
ast(&self) -> &'a DeriveInput1048     pub fn ast(&self) -> &'a DeriveInput {
1049         self.ast
1050     }
1051 
1052     /// True if any variants were omitted due to a `filter_variants` call.
omitted_variants(&self) -> bool1053     pub fn omitted_variants(&self) -> bool {
1054         self.omitted_variants
1055     }
1056 
1057     /// Runs the passed-in function once for each bound field, passing in a `BindingInfo`.
1058     /// and generating `match` arms which evaluate the returned tokens.
1059     ///
1060     /// This method will ignore variants or fields which are ignored through the
1061     /// `filter` and `filter_variant` methods.
1062     ///
1063     /// # Example
1064     /// ```
1065     /// # #[macro_use] extern crate quote;
1066     /// # extern crate synstructure;
1067     /// # #[macro_use] extern crate syn;
1068     /// # use synstructure::*;
1069     /// # fn main() {
1070     /// let di: syn::DeriveInput = parse_quote! {
1071     ///     enum A {
1072     ///         B(i32, i32),
1073     ///         C(u32),
1074     ///     }
1075     /// };
1076     /// let s = Structure::new(&di);
1077     ///
1078     /// assert_eq!(
1079     ///     s.each(|bi| quote!(println!("{:?}", #bi))).to_string(),
1080     ///
1081     ///     quote!{
1082     ///         A::B(ref __binding_0, ref __binding_1,) => {
1083     ///             { println!("{:?}", __binding_0) }
1084     ///             { println!("{:?}", __binding_1) }
1085     ///         }
1086     ///         A::C(ref __binding_0,) => {
1087     ///             { println!("{:?}", __binding_0) }
1088     ///         }
1089     ///     }.to_string()
1090     /// );
1091     /// # }
1092     /// ```
each<F, R>(&self, mut f: F) -> TokenStream where F: FnMut(&BindingInfo) -> R, R: ToTokens,1093     pub fn each<F, R>(&self, mut f: F) -> TokenStream
1094     where
1095         F: FnMut(&BindingInfo) -> R,
1096         R: ToTokens,
1097     {
1098         let mut t = TokenStream::new();
1099         for variant in &self.variants {
1100             variant.each(&mut f).to_tokens(&mut t);
1101         }
1102         if self.omitted_variants {
1103             quote!(_ => {}).to_tokens(&mut t);
1104         }
1105         t
1106     }
1107 
1108     /// Runs the passed-in function once for each bound field, passing in the
1109     /// result of the previous call, and a `BindingInfo`. generating `match`
1110     /// arms which evaluate to the resulting tokens.
1111     ///
1112     /// This method will ignore variants or fields which are ignored through the
1113     /// `filter` and `filter_variant` methods.
1114     ///
1115     /// If a variant has been ignored, it will return the `init` value.
1116     ///
1117     /// # Example
1118     /// ```
1119     /// # #[macro_use] extern crate quote;
1120     /// # extern crate synstructure;
1121     /// # #[macro_use] extern crate syn;
1122     /// # use synstructure::*;
1123     /// # fn main() {
1124     /// let di: syn::DeriveInput = parse_quote! {
1125     ///     enum A {
1126     ///         B(i32, i32),
1127     ///         C(u32),
1128     ///     }
1129     /// };
1130     /// let s = Structure::new(&di);
1131     ///
1132     /// assert_eq!(
1133     ///     s.fold(quote!(0), |acc, bi| quote!(#acc + #bi)).to_string(),
1134     ///
1135     ///     quote!{
1136     ///         A::B(ref __binding_0, ref __binding_1,) => {
1137     ///             0 + __binding_0 + __binding_1
1138     ///         }
1139     ///         A::C(ref __binding_0,) => {
1140     ///             0 + __binding_0
1141     ///         }
1142     ///     }.to_string()
1143     /// );
1144     /// # }
1145     /// ```
fold<F, I, R>(&self, init: I, mut f: F) -> TokenStream where F: FnMut(TokenStream, &BindingInfo) -> R, I: ToTokens, R: ToTokens,1146     pub fn fold<F, I, R>(&self, init: I, mut f: F) -> TokenStream
1147     where
1148         F: FnMut(TokenStream, &BindingInfo) -> R,
1149         I: ToTokens,
1150         R: ToTokens,
1151     {
1152         let mut t = TokenStream::new();
1153         for variant in &self.variants {
1154             variant.fold(&init, &mut f).to_tokens(&mut t);
1155         }
1156         if self.omitted_variants {
1157             quote!(_ => { #init }).to_tokens(&mut t);
1158         }
1159         t
1160     }
1161 
1162     /// Runs the passed-in function once for each variant, passing in a
1163     /// `VariantInfo`. and generating `match` arms which evaluate the returned
1164     /// tokens.
1165     ///
1166     /// This method will ignore variants and not bind fields which are ignored
1167     /// through the `filter` and `filter_variant` methods.
1168     ///
1169     /// # Example
1170     /// ```
1171     /// # #[macro_use] extern crate quote;
1172     /// # extern crate synstructure;
1173     /// # #[macro_use] extern crate syn;
1174     /// # use synstructure::*;
1175     /// # fn main() {
1176     /// let di: syn::DeriveInput = parse_quote! {
1177     ///     enum A {
1178     ///         B(i32, i32),
1179     ///         C(u32),
1180     ///     }
1181     /// };
1182     /// let s = Structure::new(&di);
1183     ///
1184     /// assert_eq!(
1185     ///     s.each_variant(|v| {
1186     ///         let name = &v.ast().ident;
1187     ///         quote!(println!(stringify!(#name)))
1188     ///     }).to_string(),
1189     ///
1190     ///     quote!{
1191     ///         A::B(ref __binding_0, ref __binding_1,) => {
1192     ///             println!(stringify!(B))
1193     ///         }
1194     ///         A::C(ref __binding_0,) => {
1195     ///             println!(stringify!(C))
1196     ///         }
1197     ///     }.to_string()
1198     /// );
1199     /// # }
1200     /// ```
each_variant<F, R>(&self, mut f: F) -> TokenStream where F: FnMut(&VariantInfo) -> R, R: ToTokens,1201     pub fn each_variant<F, R>(&self, mut f: F) -> TokenStream
1202     where
1203         F: FnMut(&VariantInfo) -> R,
1204         R: ToTokens,
1205     {
1206         let mut t = TokenStream::new();
1207         for variant in &self.variants {
1208             let pat = variant.pat();
1209             let body = f(variant);
1210             quote!(#pat => { #body }).to_tokens(&mut t);
1211         }
1212         if self.omitted_variants {
1213             quote!(_ => {}).to_tokens(&mut t);
1214         }
1215         t
1216     }
1217 
1218     /// Filter the bindings created by this `Structure` object. This has 2 effects:
1219     ///
1220     /// * The bindings will no longer appear in match arms generated by methods
1221     ///   on this `Structure` or its subobjects.
1222     ///
1223     /// * Impl blocks created with the `bound_impl` or `unsafe_bound_impl`
1224     ///   method only consider type parameters referenced in the types of
1225     ///   non-filtered fields.
1226     ///
1227     /// # Example
1228     /// ```
1229     /// # #[macro_use] extern crate quote;
1230     /// # extern crate synstructure;
1231     /// # #[macro_use] extern crate syn;
1232     /// # extern crate proc_macro2;
1233     /// # use synstructure::*;
1234     /// # fn main() {
1235     /// let di: syn::DeriveInput = parse_quote! {
1236     ///     enum A {
1237     ///         B{ a: i32, b: i32 },
1238     ///         C{ a: u32 },
1239     ///     }
1240     /// };
1241     /// let mut s = Structure::new(&di);
1242     ///
1243     /// s.filter(|bi| {
1244     ///     bi.ast().ident == Some(syn::Ident::new("a", proc_macro2::Span::call_site()))
1245     /// });
1246     ///
1247     /// assert_eq!(
1248     ///     s.each(|bi| quote!(println!("{:?}", #bi))).to_string(),
1249     ///
1250     ///     quote!{
1251     ///         A::B{ a: ref __binding_0, .. } => {
1252     ///             { println!("{:?}", __binding_0) }
1253     ///         }
1254     ///         A::C{ a: ref __binding_0, } => {
1255     ///             { println!("{:?}", __binding_0) }
1256     ///         }
1257     ///     }.to_string()
1258     /// );
1259     /// # }
1260     /// ```
filter<F>(&mut self, mut f: F) -> &mut Self where F: FnMut(&BindingInfo) -> bool,1261     pub fn filter<F>(&mut self, mut f: F) -> &mut Self
1262     where
1263         F: FnMut(&BindingInfo) -> bool,
1264     {
1265         for variant in &mut self.variants {
1266             variant.filter(&mut f);
1267         }
1268         self
1269     }
1270 
1271     /// Specify which bounds should be generated by impl-generating functions
1272     /// such as `gen_impl`, `bound_impl`, and `unsafe_bound_impl`.
1273     ///
1274     /// The default behaviour is to generate both field and generic bounds from
1275     /// type parameters.
1276     ///
1277     /// # Example
1278     /// ```
1279     /// # #[macro_use] extern crate quote;
1280     /// # extern crate synstructure;
1281     /// # #[macro_use] extern crate syn;
1282     /// # use synstructure::*;
1283     /// # fn main() {
1284     /// let di: syn::DeriveInput = parse_quote! {
1285     ///     enum A<T, U> {
1286     ///         B(T),
1287     ///         C(Option<U>),
1288     ///     }
1289     /// };
1290     /// let mut s = Structure::new(&di);
1291     ///
1292     /// // Limit bounds to only generics.
1293     /// s.add_bounds(AddBounds::Generics);
1294     ///
1295     /// assert_eq!(
1296     ///     s.bound_impl(quote!(krate::Trait), quote!{
1297     ///         fn a() {}
1298     ///     }).to_string(),
1299     ///     quote!{
1300     ///         #[allow(non_upper_case_globals)]
1301     ///         const _DERIVE_krate_Trait_FOR_A: () = {
1302     ///             extern crate krate;
1303     ///             impl<T, U> krate::Trait for A<T, U>
1304     ///                 where T: krate::Trait,
1305     ///                       U: krate::Trait
1306     ///             {
1307     ///                 fn a() {}
1308     ///             }
1309     ///         };
1310     ///     }.to_string()
1311     /// );
1312     /// # }
1313     /// ```
add_bounds(&mut self, mode: AddBounds) -> &mut Self1314     pub fn add_bounds(&mut self, mode: AddBounds) -> &mut Self {
1315         self.add_bounds = mode;
1316         self
1317     }
1318 
1319     /// Filter the variants matched by this `Structure` object. This has 2 effects:
1320     ///
1321     /// * Match arms destructuring these variants will no longer be generated by
1322     ///   methods on this `Structure`
1323     ///
1324     /// * Impl blocks created with the `bound_impl` or `unsafe_bound_impl`
1325     ///   method only consider type parameters referenced in the types of
1326     ///   fields in non-fitered variants.
1327     ///
1328     /// # Example
1329     /// ```
1330     /// # #[macro_use] extern crate quote;
1331     /// # extern crate synstructure;
1332     /// # #[macro_use] extern crate syn;
1333     /// # use synstructure::*;
1334     /// # fn main() {
1335     /// let di: syn::DeriveInput = parse_quote! {
1336     ///     enum A {
1337     ///         B(i32, i32),
1338     ///         C(u32),
1339     ///     }
1340     /// };
1341     ///
1342     /// let mut s = Structure::new(&di);
1343     ///
1344     /// s.filter_variants(|v| v.ast().ident != "B");
1345     ///
1346     /// assert_eq!(
1347     ///     s.each(|bi| quote!(println!("{:?}", #bi))).to_string(),
1348     ///
1349     ///     quote!{
1350     ///         A::C(ref __binding_0,) => {
1351     ///             { println!("{:?}", __binding_0) }
1352     ///         }
1353     ///         _ => {}
1354     ///     }.to_string()
1355     /// );
1356     /// # }
1357     /// ```
filter_variants<F>(&mut self, f: F) -> &mut Self where F: FnMut(&VariantInfo) -> bool,1358     pub fn filter_variants<F>(&mut self, f: F) -> &mut Self
1359     where
1360         F: FnMut(&VariantInfo) -> bool,
1361     {
1362         let before_len = self.variants.len();
1363         self.variants.retain(f);
1364         if self.variants.len() != before_len {
1365             self.omitted_variants = true;
1366         }
1367         self
1368     }
1369 
1370     /// Remove the variant at the given index.
1371     ///
1372     /// # Panics
1373     ///
1374     /// Panics if the index is out of range.
remove_variant(&mut self, idx: usize) -> &mut Self1375     pub fn remove_variant(&mut self, idx: usize) -> &mut Self {
1376         self.variants.remove(idx);
1377         self.omitted_variants = true;
1378         self
1379     }
1380 
1381     /// Updates the `BindStyle` for each of the passed-in fields by calling the
1382     /// passed-in function for each `BindingInfo`.
1383     ///
1384     /// # Example
1385     /// ```
1386     /// # #[macro_use] extern crate quote;
1387     /// # extern crate synstructure;
1388     /// # #[macro_use] extern crate syn;
1389     /// # use synstructure::*;
1390     /// # fn main() {
1391     /// let di: syn::DeriveInput = parse_quote! {
1392     ///     enum A {
1393     ///         B(i32, i32),
1394     ///         C(u32),
1395     ///     }
1396     /// };
1397     /// let mut s = Structure::new(&di);
1398     ///
1399     /// s.bind_with(|bi| BindStyle::RefMut);
1400     ///
1401     /// assert_eq!(
1402     ///     s.each(|bi| quote!(println!("{:?}", #bi))).to_string(),
1403     ///
1404     ///     quote!{
1405     ///         A::B(ref mut __binding_0, ref mut __binding_1,) => {
1406     ///             { println!("{:?}", __binding_0) }
1407     ///             { println!("{:?}", __binding_1) }
1408     ///         }
1409     ///         A::C(ref mut __binding_0,) => {
1410     ///             { println!("{:?}", __binding_0) }
1411     ///         }
1412     ///     }.to_string()
1413     /// );
1414     /// # }
1415     /// ```
bind_with<F>(&mut self, mut f: F) -> &mut Self where F: FnMut(&BindingInfo) -> BindStyle,1416     pub fn bind_with<F>(&mut self, mut f: F) -> &mut Self
1417     where
1418         F: FnMut(&BindingInfo) -> BindStyle,
1419     {
1420         for variant in &mut self.variants {
1421             variant.bind_with(&mut f);
1422         }
1423         self
1424     }
1425 
1426     /// Updates the binding name for each fo the passed-in fields by calling the
1427     /// passed-in function for each `BindingInfo`.
1428     ///
1429     /// The function will be called with the `BindingInfo` and its index in the
1430     /// enclosing variant.
1431     ///
1432     /// The default name is `__binding_{}` where `{}` is replaced with an
1433     /// increasing number.
1434     ///
1435     /// # Example
1436     /// ```
1437     /// # #[macro_use] extern crate quote;
1438     /// # extern crate synstructure;
1439     /// # #[macro_use] extern crate syn;
1440     /// # use synstructure::*;
1441     /// # fn main() {
1442     /// let di: syn::DeriveInput = parse_quote! {
1443     ///     enum A {
1444     ///         B{ a: i32, b: i32 },
1445     ///         C{ a: u32 },
1446     ///     }
1447     /// };
1448     /// let mut s = Structure::new(&di);
1449     ///
1450     /// s.binding_name(|bi, i| bi.ident.clone().unwrap());
1451     ///
1452     /// assert_eq!(
1453     ///     s.each(|bi| quote!(println!("{:?}", #bi))).to_string(),
1454     ///
1455     ///     quote!{
1456     ///         A::B{ a: ref a, b: ref b, } => {
1457     ///             { println!("{:?}", a) }
1458     ///             { println!("{:?}", b) }
1459     ///         }
1460     ///         A::C{ a: ref a, } => {
1461     ///             { println!("{:?}", a) }
1462     ///         }
1463     ///     }.to_string()
1464     /// );
1465     /// # }
1466     /// ```
binding_name<F>(&mut self, mut f: F) -> &mut Self where F: FnMut(&Field, usize) -> Ident,1467     pub fn binding_name<F>(&mut self, mut f: F) -> &mut Self
1468     where
1469         F: FnMut(&Field, usize) -> Ident,
1470     {
1471         for variant in &mut self.variants {
1472             variant.binding_name(&mut f);
1473         }
1474         self
1475     }
1476 
1477     /// Returns a list of the type parameters which are refrenced in the types
1478     /// of non-filtered fields / variants.
1479     ///
1480     /// # Caveat
1481     ///
1482     /// If the struct contains any macros in type position, all parameters will
1483     /// be considered bound. This is because we cannot determine which type
1484     /// parameters are bound by type macros.
1485     ///
1486     /// # Example
1487     /// ```
1488     /// # #[macro_use] extern crate quote;
1489     /// # extern crate synstructure;
1490     /// # #[macro_use] extern crate syn;
1491     /// # extern crate proc_macro2;
1492     /// # use synstructure::*;
1493     /// # fn main() {
1494     /// let di: syn::DeriveInput = parse_quote! {
1495     ///     enum A<T, U> {
1496     ///         B(T, i32),
1497     ///         C(Option<U>),
1498     ///     }
1499     /// };
1500     /// let mut s = Structure::new(&di);
1501     ///
1502     /// s.filter_variants(|v| v.ast().ident != "C");
1503     ///
1504     /// assert_eq!(
1505     ///     s.referenced_ty_params(),
1506     ///     &[&(syn::Ident::new("T", proc_macro2::Span::call_site()))]
1507     /// );
1508     /// # }
1509     /// ```
referenced_ty_params(&self) -> Vec<&'a Ident>1510     pub fn referenced_ty_params(&self) -> Vec<&'a Ident> {
1511         let mut flags = Vec::new();
1512         for variant in &self.variants {
1513             for binding in &variant.bindings {
1514                 generics_fuse(&mut flags, &binding.seen_generics);
1515             }
1516         }
1517         fetch_generics(&flags, &self.ast.generics)
1518     }
1519 
1520     /// Adds an `impl<>` generic parameter.
1521     /// This can be used when the trait to be derived needs some extra generic parameters.
1522     ///
1523     /// # Example
1524     /// ```
1525     /// # #![recursion_limit="128"]
1526     /// # #[macro_use] extern crate quote;
1527     /// # extern crate synstructure;
1528     /// # #[macro_use] extern crate syn;
1529     /// # use synstructure::*;
1530     /// # fn main() {
1531     /// let di: syn::DeriveInput = parse_quote! {
1532     ///     enum A<T, U> {
1533     ///         B(T),
1534     ///         C(Option<U>),
1535     ///     }
1536     /// };
1537     /// let mut s = Structure::new(&di);
1538     /// let generic: syn::GenericParam = parse_quote!(X: krate::AnotherTrait);
1539     ///
1540     /// assert_eq!(
1541     ///     s.add_impl_generic(generic)
1542     ///         .bound_impl(quote!(krate::Trait<X>),
1543     ///         quote!{
1544     ///                 fn a() {}
1545     ///         }
1546     ///     ).to_string(),
1547     ///     quote!{
1548     ///         #[allow(non_upper_case_globals)]
1549     ///         const _DERIVE_krate_Trait_X_FOR_A: () = {
1550     ///             extern crate krate;
1551     ///             impl<T, U, X: krate::AnotherTrait> krate::Trait<X> for A<T, U>
1552     ///                 where T : krate :: Trait < X >,
1553     ///                       Option<U>: krate::Trait<X>,
1554     ///                       U: krate::Trait<X>
1555     ///             {
1556     ///                 fn a() {}
1557     ///             }
1558     ///         };
1559     ///     }.to_string()
1560     /// );
1561     /// # }
1562     /// ```
add_impl_generic(&mut self, param: GenericParam) -> &mut Self1563     pub fn add_impl_generic(&mut self, param: GenericParam) -> &mut Self {
1564         self.extra_impl.push(param);
1565         self
1566     }
1567 
1568     /// Add trait bounds for a trait with the given path for each type parmaeter
1569     /// referenced in the types of non-filtered fields.
1570     ///
1571     /// # Caveat
1572     ///
1573     /// If the method contains any macros in type position, all parameters will
1574     /// be considered bound. This is because we cannot determine which type
1575     /// parameters are bound by type macros.
add_trait_bounds( &self, bound: &TraitBound, where_clause: &mut Option<WhereClause>, mode: AddBounds, )1576     pub fn add_trait_bounds(
1577         &self,
1578         bound: &TraitBound,
1579         where_clause: &mut Option<WhereClause>,
1580         mode: AddBounds,
1581     ) {
1582         let mut seen = HashSet::new();
1583         let mut pred = |ty: Type| if !seen.contains(&ty) {
1584             seen.insert(ty.clone());
1585 
1586             // Ensure we have a where clause, because we need to use it. We
1587             // can't use `get_or_insert_with`, because it isn't supported on all
1588             // rustc versions we support (this is a Rust 1.20+ feature).
1589             if where_clause.is_none() {
1590                 *where_clause = Some(WhereClause {
1591                     where_token: Default::default(),
1592                     predicates: punctuated::Punctuated::new(),
1593                 });
1594             }
1595             let clause = where_clause.as_mut().unwrap();
1596 
1597             // Add a predicate.
1598             clause.predicates.push(WherePredicate::Type(PredicateType {
1599                 lifetimes: None,
1600                 bounded_ty: ty,
1601                 colon_token: Default::default(),
1602                 bounds: Some(punctuated::Pair::End(TypeParamBound::Trait(bound.clone())))
1603                     .into_iter()
1604                     .collect(),
1605             }));
1606         };
1607 
1608         for variant in &self.variants {
1609             for binding in &variant.bindings {
1610                 match mode {
1611                     AddBounds::Both | AddBounds::Fields => {
1612                         for &seen in &binding.seen_generics {
1613                             if seen {
1614                                 pred(binding.ast().ty.clone());
1615                                 break;
1616                             }
1617                         }
1618                     }
1619                     _ => {}
1620                 }
1621 
1622                 match mode {
1623                     AddBounds::Both | AddBounds::Generics => {
1624                         for param in binding.referenced_ty_params() {
1625                             pred(Type::Path(TypePath {
1626                                 qself: None,
1627                                 path: (*param).clone().into(),
1628                             }));
1629                         }
1630                     }
1631                     _ => {}
1632                 }
1633             }
1634         }
1635     }
1636 
1637     /// > NOTE: This methods' features are superceded by `Structure::gen_impl`.
1638     ///
1639     /// Creates an `impl` block with the required generic type fields filled in
1640     /// to implement the trait `path`.
1641     ///
1642     /// This method also adds where clauses to the impl requiring that all
1643     /// referenced type parmaeters implement the trait `path`.
1644     ///
1645     /// # Hygiene and Paths
1646     ///
1647     /// This method wraps the impl block inside of a `const` (see the example
1648     /// below). In this scope, the first segment of the passed-in path is
1649     /// `extern crate`-ed in. If you don't want to generate that `extern crate`
1650     /// item, use a global path.
1651     ///
1652     /// This means that if you are implementing `my_crate::Trait`, you simply
1653     /// write `s.bound_impl(quote!(my_crate::Trait), quote!(...))`, and for the
1654     /// entirety of the definition, you can refer to your crate as `my_crate`.
1655     ///
1656     /// # Caveat
1657     ///
1658     /// If the method contains any macros in type position, all parameters will
1659     /// be considered bound. This is because we cannot determine which type
1660     /// parameters are bound by type macros.
1661     ///
1662     /// # Panics
1663     ///
1664     /// Panics if the path string parameter is not a valid `TraitBound`.
1665     ///
1666     /// # Example
1667     /// ```
1668     /// # #[macro_use] extern crate quote;
1669     /// # extern crate synstructure;
1670     /// # #[macro_use] extern crate syn;
1671     /// # use synstructure::*;
1672     /// # fn main() {
1673     /// let di: syn::DeriveInput = parse_quote! {
1674     ///     enum A<T, U> {
1675     ///         B(T),
1676     ///         C(Option<U>),
1677     ///     }
1678     /// };
1679     /// let mut s = Structure::new(&di);
1680     ///
1681     /// s.filter_variants(|v| v.ast().ident != "B");
1682     ///
1683     /// assert_eq!(
1684     ///     s.bound_impl(quote!(krate::Trait), quote!{
1685     ///         fn a() {}
1686     ///     }).to_string(),
1687     ///     quote!{
1688     ///         #[allow(non_upper_case_globals)]
1689     ///         const _DERIVE_krate_Trait_FOR_A: () = {
1690     ///             extern crate krate;
1691     ///             impl<T, U> krate::Trait for A<T, U>
1692     ///                 where Option<U>: krate::Trait,
1693     ///                       U: krate::Trait
1694     ///             {
1695     ///                 fn a() {}
1696     ///             }
1697     ///         };
1698     ///     }.to_string()
1699     /// );
1700     /// # }
1701     /// ```
bound_impl<P: ToTokens,B: ToTokens>(&self, path: P, body: B) -> TokenStream1702     pub fn bound_impl<P: ToTokens,B: ToTokens>(&self, path: P, body: B) -> TokenStream {
1703         self.impl_internal(
1704             path.into_token_stream(),
1705             body.into_token_stream(),
1706             quote!(),
1707             None,
1708         )
1709     }
1710 
1711     /// > NOTE: This methods' features are superceded by `Structure::gen_impl`.
1712     ///
1713     /// Creates an `impl` block with the required generic type fields filled in
1714     /// to implement the unsafe trait `path`.
1715     ///
1716     /// This method also adds where clauses to the impl requiring that all
1717     /// referenced type parmaeters implement the trait `path`.
1718     ///
1719     /// # Hygiene and Paths
1720     ///
1721     /// This method wraps the impl block inside of a `const` (see the example
1722     /// below). In this scope, the first segment of the passed-in path is
1723     /// `extern crate`-ed in. If you don't want to generate that `extern crate`
1724     /// item, use a global path.
1725     ///
1726     /// This means that if you are implementing `my_crate::Trait`, you simply
1727     /// write `s.bound_impl(quote!(my_crate::Trait), quote!(...))`, and for the
1728     /// entirety of the definition, you can refer to your crate as `my_crate`.
1729     ///
1730     /// # Caveat
1731     ///
1732     /// If the method contains any macros in type position, all parameters will
1733     /// be considered bound. This is because we cannot determine which type
1734     /// parameters are bound by type macros.
1735     ///
1736     /// # Panics
1737     ///
1738     /// Panics if the path string parameter is not a valid `TraitBound`.
1739     ///
1740     /// # Example
1741     /// ```
1742     /// # #[macro_use] extern crate quote;
1743     /// # extern crate synstructure;
1744     /// # #[macro_use] extern crate syn;
1745     /// # use synstructure::*;
1746     /// # fn main() {
1747     /// let di: syn::DeriveInput = parse_quote! {
1748     ///     enum A<T, U> {
1749     ///         B(T),
1750     ///         C(Option<U>),
1751     ///     }
1752     /// };
1753     /// let mut s = Structure::new(&di);
1754     ///
1755     /// s.filter_variants(|v| v.ast().ident != "B");
1756     ///
1757     /// assert_eq!(
1758     ///     s.unsafe_bound_impl(quote!(krate::Trait), quote!{
1759     ///         fn a() {}
1760     ///     }).to_string(),
1761     ///     quote!{
1762     ///         #[allow(non_upper_case_globals)]
1763     ///         const _DERIVE_krate_Trait_FOR_A: () = {
1764     ///             extern crate krate;
1765     ///             unsafe impl<T, U> krate::Trait for A<T, U>
1766     ///                 where Option<U>: krate::Trait,
1767     ///                       U: krate::Trait
1768     ///             {
1769     ///                 fn a() {}
1770     ///             }
1771     ///         };
1772     ///     }.to_string()
1773     /// );
1774     /// # }
1775     /// ```
unsafe_bound_impl<P: ToTokens, B: ToTokens>(&self, path: P, body: B) -> TokenStream1776     pub fn unsafe_bound_impl<P: ToTokens, B: ToTokens>(&self, path: P, body: B) -> TokenStream {
1777         self.impl_internal(
1778             path.into_token_stream(),
1779             body.into_token_stream(),
1780             quote!(unsafe),
1781             None,
1782         )
1783     }
1784 
1785     /// > NOTE: This methods' features are superceded by `Structure::gen_impl`.
1786     ///
1787     /// Creates an `impl` block with the required generic type fields filled in
1788     /// to implement the trait `path`.
1789     ///
1790     /// This method will not add any where clauses to the impl.
1791     ///
1792     /// # Hygiene and Paths
1793     ///
1794     /// This method wraps the impl block inside of a `const` (see the example
1795     /// below). In this scope, the first segment of the passed-in path is
1796     /// `extern crate`-ed in. If you don't want to generate that `extern crate`
1797     /// item, use a global path.
1798     ///
1799     /// This means that if you are implementing `my_crate::Trait`, you simply
1800     /// write `s.bound_impl(quote!(my_crate::Trait), quote!(...))`, and for the
1801     /// entirety of the definition, you can refer to your crate as `my_crate`.
1802     ///
1803     /// # Panics
1804     ///
1805     /// Panics if the path string parameter is not a valid `TraitBound`.
1806     ///
1807     /// # Example
1808     /// ```
1809     /// # #[macro_use] extern crate quote;
1810     /// # extern crate synstructure;
1811     /// # #[macro_use] extern crate syn;
1812     /// # use synstructure::*;
1813     /// # fn main() {
1814     /// let di: syn::DeriveInput = parse_quote! {
1815     ///     enum A<T, U> {
1816     ///         B(T),
1817     ///         C(Option<U>),
1818     ///     }
1819     /// };
1820     /// let mut s = Structure::new(&di);
1821     ///
1822     /// s.filter_variants(|v| v.ast().ident != "B");
1823     ///
1824     /// assert_eq!(
1825     ///     s.unbound_impl(quote!(krate::Trait), quote!{
1826     ///         fn a() {}
1827     ///     }).to_string(),
1828     ///     quote!{
1829     ///         #[allow(non_upper_case_globals)]
1830     ///         const _DERIVE_krate_Trait_FOR_A: () = {
1831     ///             extern crate krate;
1832     ///             impl<T, U> krate::Trait for A<T, U> {
1833     ///                 fn a() {}
1834     ///             }
1835     ///         };
1836     ///     }.to_string()
1837     /// );
1838     /// # }
1839     /// ```
unbound_impl<P: ToTokens, B: ToTokens>(&self, path: P, body: B) -> TokenStream1840     pub fn unbound_impl<P: ToTokens, B: ToTokens>(&self, path: P, body: B) -> TokenStream {
1841         self.impl_internal(
1842             path.into_token_stream(),
1843             body.into_token_stream(),
1844             quote!(),
1845             Some(AddBounds::None),
1846         )
1847     }
1848 
1849     /// > NOTE: This methods' features are superceded by `Structure::gen_impl`.
1850     ///
1851     /// Creates an `impl` block with the required generic type fields filled in
1852     /// to implement the unsafe trait `path`.
1853     ///
1854     /// This method will not add any where clauses to the impl.
1855     ///
1856     /// # Hygiene and Paths
1857     ///
1858     /// This method wraps the impl block inside of a `const` (see the example
1859     /// below). In this scope, the first segment of the passed-in path is
1860     /// `extern crate`-ed in. If you don't want to generate that `extern crate`
1861     /// item, use a global path.
1862     ///
1863     /// This means that if you are implementing `my_crate::Trait`, you simply
1864     /// write `s.bound_impl(quote!(my_crate::Trait), quote!(...))`, and for the
1865     /// entirety of the definition, you can refer to your crate as `my_crate`.
1866     ///
1867     /// # Panics
1868     ///
1869     /// Panics if the path string parameter is not a valid `TraitBound`.
1870     ///
1871     /// # Example
1872     /// ```
1873     /// # #[macro_use] extern crate quote;
1874     /// # extern crate synstructure;
1875     /// # #[macro_use] extern crate syn;
1876     /// # use synstructure::*;
1877     /// # fn main() {
1878     /// let di: syn::DeriveInput = parse_quote! {
1879     ///     enum A<T, U> {
1880     ///         B(T),
1881     ///         C(Option<U>),
1882     ///     }
1883     /// };
1884     /// let mut s = Structure::new(&di);
1885     ///
1886     /// s.filter_variants(|v| v.ast().ident != "B");
1887     ///
1888     /// assert_eq!(
1889     ///     s.unsafe_unbound_impl(quote!(krate::Trait), quote!{
1890     ///         fn a() {}
1891     ///     }).to_string(),
1892     ///     quote!{
1893     ///         #[allow(non_upper_case_globals)]
1894     ///         const _DERIVE_krate_Trait_FOR_A: () = {
1895     ///             extern crate krate;
1896     ///             unsafe impl<T, U> krate::Trait for A<T, U> {
1897     ///                 fn a() {}
1898     ///             }
1899     ///         };
1900     ///     }.to_string()
1901     /// );
1902     /// # }
1903     /// ```
1904     #[deprecated]
unsafe_unbound_impl<P: ToTokens, B: ToTokens>(&self, path: P, body: B) -> TokenStream1905     pub fn unsafe_unbound_impl<P: ToTokens, B: ToTokens>(&self, path: P, body: B) -> TokenStream {
1906         self.impl_internal(
1907             path.into_token_stream(),
1908             body.into_token_stream(),
1909             quote!(unsafe),
1910             Some(AddBounds::None),
1911         )
1912     }
1913 
impl_internal( &self, path: TokenStream, body: TokenStream, safety: TokenStream, mode: Option<AddBounds>, ) -> TokenStream1914     fn impl_internal(
1915         &self,
1916         path: TokenStream,
1917         body: TokenStream,
1918         safety: TokenStream,
1919         mode: Option<AddBounds>,
1920     ) -> TokenStream {
1921         let mode = mode.unwrap_or(self.add_bounds);
1922         let name = &self.ast.ident;
1923         let mut gen_clone = self.ast.generics.clone();
1924         gen_clone.params.extend(self.extra_impl.clone().into_iter());
1925         let (impl_generics, _, _) = gen_clone.split_for_impl();
1926         let (_, ty_generics, where_clause) = self.ast.generics.split_for_impl();
1927 
1928         let bound = syn::parse2::<TraitBound>(path.into())
1929             .expect("`path` argument must be a valid rust trait bound");
1930 
1931         let mut where_clause = where_clause.cloned();
1932         self.add_trait_bounds(&bound, &mut where_clause, mode);
1933 
1934         let dummy_const: Ident = sanitize_ident(&format!(
1935             "_DERIVE_{}_FOR_{}",
1936             (&bound).into_token_stream(),
1937             name.into_token_stream(),
1938         ));
1939 
1940         // This function is smart. If a global path is passed, no extern crate
1941         // statement will be generated, however, a relative path will cause the
1942         // crate which it is relative to to be imported within the current
1943         // scope.
1944         let mut extern_crate = quote!();
1945         if bound.path.leading_colon.is_none() {
1946             if let Some(ref seg) = bound.path.segments.first() {
1947                 let seg = seg.value();
1948                 extern_crate = quote! { extern crate #seg; };
1949             }
1950         }
1951 
1952         quote! {
1953             #[allow(non_upper_case_globals)]
1954             const #dummy_const: () = {
1955                 #extern_crate
1956                 #safety impl #impl_generics #bound for #name #ty_generics #where_clause {
1957                     #body
1958                 }
1959             };
1960         }
1961     }
1962 
1963     /// Generate an impl block for the given struct. This impl block will
1964     /// automatically use hygiene tricks to avoid polluting the caller's
1965     /// namespace, and will automatically add trait bounds for generic type
1966     /// parameters.
1967     ///
1968     /// # Syntax
1969     ///
1970     /// This function accepts its arguments as a `TokenStream`. The recommended way
1971     /// to call this function is passing the result of invoking the `quote!`
1972     /// macro to it.
1973     ///
1974     /// ```ignore
1975     /// s.gen_impl(quote! {
1976     ///     // You can write any items which you want to import into scope here.
1977     ///     // For example, you may want to include an `extern crate` for the
1978     ///     // crate which implements your trait. These items will only be
1979     ///     // visible to the code you generate, and won't be exposed to the
1980     ///     // consuming crate
1981     ///     extern crate krate;
1982     ///
1983     ///     // You can also add `use` statements here to bring types or traits
1984     ///     // into scope.
1985     ///     //
1986     ///     // WARNING: Try not to use common names here, because the stable
1987     ///     // version of syn does not support hygiene and you could accidentally
1988     ///     // shadow types from the caller crate.
1989     ///     use krate::Trait as MyTrait;
1990     ///
1991     ///     // The actual impl block is a `gen impl` or `gen unsafe impl` block.
1992     ///     // You can use `@Self` to refer to the structure's type.
1993     ///     gen impl MyTrait for @Self {
1994     ///         fn f(&self) { ... }
1995     ///     }
1996     /// })
1997     /// ```
1998     ///
1999     /// The most common usage of this trait involves loading the crate the
2000     /// target trait comes from with `extern crate`, and then invoking a `gen
2001     /// impl` block.
2002     ///
2003     /// # Hygiene
2004     ///
2005     /// This method tries to handle hygiene intelligenly for both stable and
2006     /// unstable proc-macro implementations, however there are visible
2007     /// differences.
2008     ///
2009     /// The output of every `gen_impl` function is wrapped in a dummy `const`
2010     /// value, to ensure that it is given its own scope, and any values brought
2011     /// into scope are not leaked to the calling crate. For example, the above
2012     /// invocation may generate an output like the following:
2013     ///
2014     /// ```ignore
2015     /// const _DERIVE_krate_Trait_FOR_Struct: () = {
2016     ///     extern crate krate;
2017     ///     use krate::Trait as MyTrait;
2018     ///     impl<T> MyTrait for Struct<T> where T: MyTrait {
2019     ///         fn f(&self) { ... }
2020     ///     }
2021     /// };
2022     /// ```
2023     ///
2024     /// ### Using the `std` crate
2025     ///
2026     /// If you are using `quote!()` to implement your trait, with the
2027     /// `proc-macro2/nightly` feature, `std` isn't considered to be in scope for
2028     /// your macro. This means that if you use types from `std` in your
2029     /// procedural macro, you'll want to explicitly load it with an `extern
2030     /// crate std;`.
2031     ///
2032     /// ### Absolute paths
2033     ///
2034     /// You should generally avoid using absolute paths in your generated code,
2035     /// as they will resolve very differently when using the stable and nightly
2036     /// versions of `proc-macro2`. Instead, load the crates you need to use
2037     /// explictly with `extern crate` and
2038     ///
2039     /// # Trait Bounds
2040     ///
2041     /// This method will automatically add trait bounds for any type parameters
2042     /// which are referenced within the types of non-ignored fields.
2043     ///
2044     /// Additional type parameters may be added with the generics syntax after
2045     /// the `impl` keyword.
2046     ///
2047     /// ### Type Macro Caveat
2048     ///
2049     /// If the method contains any macros in type position, all parameters will
2050     /// be considered bound. This is because we cannot determine which type
2051     /// parameters are bound by type macros.
2052     ///
2053     /// # Panics
2054     ///
2055     /// This function will panic if the input `TokenStream` is not well-formed, or
2056     /// if additional type parameters added by `impl<..>` conflict with generic
2057     /// type parameters on the original struct.
2058     ///
2059     /// # Example Usage
2060     ///
2061     /// ```
2062     /// # #![recursion_limit="128"]
2063     /// # #[macro_use] extern crate quote;
2064     /// # extern crate synstructure;
2065     /// # #[macro_use] extern crate syn;
2066     /// # use synstructure::*;
2067     /// # fn main() {
2068     /// let di: syn::DeriveInput = parse_quote! {
2069     ///     enum A<T, U> {
2070     ///         B(T),
2071     ///         C(Option<U>),
2072     ///     }
2073     /// };
2074     /// let mut s = Structure::new(&di);
2075     ///
2076     /// s.filter_variants(|v| v.ast().ident != "B");
2077     ///
2078     /// assert_eq!(
2079     ///     s.gen_impl(quote! {
2080     ///         extern crate krate;
2081     ///         gen impl krate::Trait for @Self {
2082     ///             fn a() {}
2083     ///         }
2084     ///     }).to_string(),
2085     ///     quote!{
2086     ///         #[allow(non_upper_case_globals)]
2087     ///         const _DERIVE_krate_Trait_FOR_A: () = {
2088     ///             extern crate krate;
2089     ///             impl<T, U> krate::Trait for A<T, U>
2090     ///             where
2091     ///                 Option<U>: krate::Trait,
2092     ///                 U: krate::Trait
2093     ///             {
2094     ///                 fn a() {}
2095     ///             }
2096     ///         };
2097     ///     }.to_string()
2098     /// );
2099     ///
2100     /// // NOTE: You can also add extra generics after the impl
2101     /// assert_eq!(
2102     ///     s.gen_impl(quote! {
2103     ///         extern crate krate;
2104     ///         gen impl<X: krate::OtherTrait> krate::Trait<X> for @Self
2105     ///         where
2106     ///             X: Send + Sync,
2107     ///         {
2108     ///             fn a() {}
2109     ///         }
2110     ///     }).to_string(),
2111     ///     quote!{
2112     ///         #[allow(non_upper_case_globals)]
2113     ///         const _DERIVE_krate_Trait_X_FOR_A: () = {
2114     ///             extern crate krate;
2115     ///             impl<X: krate::OtherTrait, T, U> krate::Trait<X> for A<T, U>
2116     ///             where
2117     ///                 X: Send + Sync,
2118     ///                 Option<U>: krate::Trait<X>,
2119     ///                 U: krate::Trait<X>
2120     ///             {
2121     ///                 fn a() {}
2122     ///             }
2123     ///         };
2124     ///     }.to_string()
2125     /// );
2126     /// # }
2127     /// ```
2128     ///
2129     /// Use `add_bounds` to change which bounds are generated.
gen_impl(&self, cfg: TokenStream) -> TokenStream2130     pub fn gen_impl(&self, cfg: TokenStream) -> TokenStream {
2131         use syn::parse::{Parser, ParseStream, Result};
2132 
2133         // Syn requires parsers to be methods conforming to a strict signature
2134         let do_parse = |input: ParseStream| -> Result<TokenStream> {
2135             // Helper lambda to parse the prefix of a gen block.
2136             let parse_prefix = |input: ParseStream| -> Result<_> {
2137                 if input.parse::<Ident>()? != "gen" {
2138                     return Err(input.error(""));
2139                 }
2140                 let safety = input.parse::<Option<Token![unsafe]>>()?;
2141                 let _ = input.parse::<Token![impl]>()?;
2142                 Ok(safety)
2143             };
2144 
2145             let mut before = vec![];
2146             loop {
2147                 if let Ok(_) = parse_prefix(&input.fork()) {
2148                     break;
2149                 }
2150                 before.push(input.parse::<TokenTree>()?);
2151             }
2152 
2153             // Parse the prefix "for real"
2154             let safety = parse_prefix(input)?;
2155 
2156             // optional `<>`
2157             let mut generics = input.parse::<Generics>()?;
2158 
2159             // @bound
2160             let bound = input.parse::<TraitBound>()?;
2161 
2162             // `for @Self`
2163             let _ = input.parse::<Token![for]>()?;
2164             let _ = input.parse::<Token![@]>()?;
2165             let _ = input.parse::<Token![Self]>()?;
2166 
2167             // optional `where ...`
2168             generics.where_clause = input.parse()?;
2169 
2170             // Body of the impl
2171             let body;
2172             braced!(body in input);
2173             let body = body.parse::<TokenStream>()?;
2174 
2175             // Tokens following impl
2176             let after = input.parse::<TokenStream>()?;
2177 
2178             /* Codegen Logic */
2179             let name = &self.ast.ident;
2180 
2181             // Add the generics from the original struct in, and then add any
2182             // additional trait bounds which we need on the type.
2183             merge_generics(&mut generics, &self.ast.generics);
2184             self.add_trait_bounds(&bound, &mut generics.where_clause, self.add_bounds);
2185             let (impl_generics, _, where_clause) = generics.split_for_impl();
2186             let (_, ty_generics, _) = self.ast.generics.split_for_impl();
2187 
2188             let dummy_const: Ident = sanitize_ident(&format!(
2189                 "_DERIVE_{}_FOR_{}",
2190                 (&bound).into_token_stream(),
2191                 name.into_token_stream(),
2192             ));
2193 
2194             Ok(quote! {
2195                 #[allow(non_upper_case_globals)]
2196                 const #dummy_const: () = {
2197                     #(#before)*
2198                     #safety impl #impl_generics #bound for #name #ty_generics #where_clause {
2199                         #body
2200                     }
2201                     #after
2202                 };
2203             })
2204         };
2205         Parser::parse2(do_parse, cfg).expect("Failed to parse gen_impl")
2206     }
2207 }
2208 
2209 /// Dumps an unpretty version of a tokenstream. Takes any type which implements
2210 /// `Display`.
2211 ///
2212 /// This is mostly useful for visualizing the output of a procedural macro, as
2213 /// it makes it marginally more readable. It is used in the implementation of
2214 /// `test_derive!` to unprettily print the output.
2215 ///
2216 /// # Stability
2217 ///
2218 /// The stability of the output of this function is not guaranteed. Do not
2219 /// assert that the output of this function does not change between minor
2220 /// versions.
2221 ///
2222 /// # Example
2223 ///
2224 /// ```
2225 /// # extern crate synstructure;
2226 /// # #[macro_use] extern crate quote;
2227 /// # fn main() {
2228 /// assert_eq!(
2229 ///     synstructure::unpretty_print(quote! {
2230 ///         #[allow(non_upper_case_globals)]
2231 ///         const _DERIVE_krate_Trait_FOR_A: () = {
2232 ///             extern crate krate;
2233 ///             impl<T, U> krate::Trait for A<T, U>
2234 ///             where
2235 ///                 Option<U>: krate::Trait,
2236 ///                 U: krate::Trait
2237 ///             {
2238 ///                 fn a() {}
2239 ///             }
2240 ///         };
2241 ///     }),
2242 ///     "# [
2243 ///     allow (
2244 ///         non_upper_case_globals )
2245 ///     ]
2246 /// const _DERIVE_krate_Trait_FOR_A : (
2247 ///     )
2248 /// = {
2249 ///     extern crate krate ;
2250 ///     impl < T , U > krate :: Trait for A < T , U > where Option < U > : krate :: Trait , U : krate :: Trait {
2251 ///         fn a (
2252 ///             )
2253 ///         {
2254 ///             }
2255 ///         }
2256 ///     }
2257 /// ;
2258 /// "
2259 /// )
2260 /// # }
2261 /// ```
unpretty_print<T: std::fmt::Display>(ts: T) -> String2262 pub fn unpretty_print<T: std::fmt::Display>(ts: T) -> String {
2263     let mut res = String::new();
2264 
2265     let raw_s = ts.to_string();
2266     let mut s = &raw_s[..];
2267     let mut indent = 0;
2268     while let Some(i) = s.find(&['(', '{', '[', ')', '}', ']', ';'][..]) {
2269         match &s[i..i + 1] {
2270             "(" | "{" | "[" => indent += 1,
2271             ")" | "}" | "]" => indent -= 1,
2272             _ => {}
2273         }
2274         res.push_str(&s[..i + 1]);
2275         res.push('\n');
2276         for _ in 0..indent {
2277             res.push_str("    ");
2278         }
2279         s = s[i + 1..].trim_left_matches(' ');
2280     }
2281     res.push_str(s);
2282     res
2283 }
2284