synstructure/
lib.rs

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