1#![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#[doc(hidden)]
179pub use quote::quote;
180
181use proc_macro2::{Span, TokenStream, TokenTree};
182
183#[doc(hidden)]
187pub mod macros;
188
189#[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 Both,
195 Fields,
197 Generics,
199 None,
201 #[doc(hidden)]
202 __Nonexhaustive,
203}
204
205#[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 Move,
210 MoveMut,
212 Ref,
214 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
229fn 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
241fn 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
254fn merge_generics(into: &mut Generics, from: &Generics) -> Result<()> {
256 for p in &from.params {
258 for op in &into.params {
259 match (op, p) {
260 (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 (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 _ => (),
286 }
287 }
288 into.params.push(p.clone());
289 }
290
291 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
301fn 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#[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 pub binding: Ident,
328
329 pub style: BindStyle,
331
332 field: &'a Field,
333
334 generics: &'a Generics,
336 seen_generics: Vec<bool>,
337 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 pub fn ast(&self) -> &'a Field {
352 self.field
353 }
354
355 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 pub fn referenced_ty_params(&self) -> Vec<&'a Ident> {
406 fetch_generics(&self.seen_generics, self.generics)
407 }
408}
409
410#[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#[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 original_length: usize,
432}
433
434fn get_ty_params(field: &Field, generics: &Generics) -> Vec<bool> {
438 struct BoundTypeLocator<'a> {
441 result: Vec<bool>,
442 generics: &'a Generics,
443 }
444
445 impl<'a> Visit<'a> for BoundTypeLocator<'a> {
446 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 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 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 pub fn bindings(&self) -> &[BindingInfo<'a>] {
517 &self.bindings
518 }
519
520 pub fn bindings_mut(&mut self) -> &mut [BindingInfo<'a>] {
522 &mut self.bindings
523 }
524
525 pub fn ast(&self) -> VariantAst<'a> {
528 self.ast
529 }
530
531 pub fn omitted_bindings(&self) -> bool {
533 self.original_length != self.bindings.len()
534 }
535
536 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 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 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 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 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 #[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 pub fn remove_binding(&mut self, idx: usize) -> &mut Self {
865 self.bindings.remove(idx);
866 self
867 }
868
869 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 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 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#[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 pub fn new(ast: &'a DeriveInput) -> Self {
1010 Self::try_new(ast).expect("Unable to create synstructure::Structure")
1011 }
1012
1013 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 pub fn variants(&self) -> &[VariantInfo<'a>] {
1067 &self.variants
1068 }
1069
1070 pub fn variants_mut(&mut self) -> &mut [VariantInfo<'a>] {
1072 &mut self.variants
1073 }
1074
1075 pub fn ast(&self) -> &'a DeriveInput {
1078 self.ast
1079 }
1080
1081 pub fn omitted_variants(&self) -> bool {
1083 self.omitted_variants
1084 }
1085
1086 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 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 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 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 #[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 pub fn add_where_predicate(&mut self, pred: WherePredicate) -> &mut Self {
1385 self.extra_predicates.push(pred);
1386 self
1387 }
1388
1389 pub fn add_bounds(&mut self, mode: AddBounds) -> &mut Self {
1427 self.add_bounds = mode;
1428 self
1429 }
1430
1431 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 #[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 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 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 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 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 pub fn add_impl_generic(&mut self, param: GenericParam) -> &mut Self {
1710 self.extra_impl.push(param);
1711 self
1712 }
1713
1714 pub fn add_trait_bounds(
1723 &self,
1724 bound: &TraitBound,
1725 where_clause: &mut Option<WhereClause>,
1726 mode: AddBounds,
1727 ) {
1728 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 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 pub fn underscore_const(&mut self, _enabled: bool) -> &mut Self {
1793 self
1794 }
1795
1796 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 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 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 #[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 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 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 let safety = parse_prefix(input)?;
2321
2322 let mut generics = input.parse::<Generics>()?;
2324
2325 let bound = input.parse::<TraitBound>()?;
2327
2328 let _ = input.parse::<::syn::token::ForToken![for]>()?;
2330 let _ = input.parse::<::syn::token::AtToken![@]>()?;
2331 let _ = input.parse::<::syn::token::SelfTypeToken![Self]>()?;
2332
2333 generics.where_clause = input.parse()?;
2335
2336 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 let maybe_next_impl = self.gen_impl_parse(&input.fork(), false);
2344
2345 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 let name = &self.ast.ident;
2355
2356 if let Err(err) = merge_generics(&mut generics, &self.ast.generics) {
2359 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
2386pub 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#[allow(deprecated)]
2458fn trim_start_matches(s: &str, c: char) -> &str {
2459 s.trim_left_matches(c)
2460}
2461
2462pub trait MacroResult {
2465 fn into_result(self) -> Result<TokenStream>;
2467
2468 #[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 #[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}