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