Skip to main content

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