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) -> AddBounds { *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: &AddBounds) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
#[allow(clippy::manual_non_exhaustive)]
impl ::core::cmp::Eq for AddBounds {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}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) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, 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) -> BindStyle { *self }
}Clone, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for BindStyle { }
#[automatically_derived]
impl ::core::cmp::PartialEq for BindStyle {
#[inline]
fn eq(&self, other: &BindStyle) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for BindStyle {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for BindStyle {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, 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)) => {
261 if otp.ident == tp.ident {
263 return Err(Error::new_spanned(
264 p,
265 ::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!(
266 "Attempted to merge conflicting generic parameters: {} and {}",
267 quote!(#op),
268 quote!(#p)
269 ),
270 ));
271 }
272 }
273 (GenericParam::Lifetime(olp), GenericParam::Lifetime(lp)) => {
274 if olp.lifetime == lp.lifetime {
276 return Err(Error::new_spanned(
277 p,
278 ::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!(
279 "Attempted to merge conflicting generic parameters: {} and {}",
280 quote!(#op),
281 quote!(#p)
282 ),
283 ));
284 }
285 }
286 _ => (),
288 }
289 }
290 into.params.push(p.clone());
291 }
292
293 if let Some(from_clause) = &from.where_clause {
295 into.make_where_clause()
296 .predicates
297 .extend(from_clause.predicates.iter().cloned());
298 }
299
300 Ok(())
301}
302
303fn get_or_insert_with<T, F>(opt: &mut Option<T>, f: F) -> &mut T
307where
308 F: FnOnce() -> T,
309{
310 if opt.is_none() {
311 *opt = Some(f());
312 }
313
314 match opt {
315 Some(v) => v,
316 None => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
317 }
318}
319
320#[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) -> BindingInfo<'a> {
BindingInfo {
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: &BindingInfo<'a>) -> 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)]
327pub struct BindingInfo<'a> {
328 pub binding: Ident,
330
331 pub style: BindStyle,
333
334 field: &'a Field,
335
336 generics: &'a Generics,
338 seen_generics: Vec<bool>,
339 index: usize,
342}
343
344impl ToTokens for BindingInfo<'_> {
345 fn to_tokens(&self, tokens: &mut TokenStream) {
346 self.binding.to_tokens(tokens);
347 }
348}
349
350impl<'a> BindingInfo<'a> {
351 pub fn ast(&self) -> &'a Field {
354 self.field
355 }
356
357 pub fn pat(&self) -> TokenStream {
378 let BindingInfo { binding, style, .. } = self;
379 {
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)
380 }
381
382 pub fn referenced_ty_params(&self) -> Vec<&'a Ident> {
408 fetch_generics(&self.seen_generics, self.generics)
409 }
410}
411
412#[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) -> VariantAst<'a> {
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: &VariantAst<'a>) -> 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)]
417pub struct VariantAst<'a> {
418 pub attrs: &'a [Attribute],
419 pub ident: &'a Ident,
420 pub fields: &'a Fields,
421 pub discriminant: &'a Option<(token::Eq, Expr)>,
422}
423
424#[derive(#[automatically_derived]
impl<'a> ::core::fmt::Debug for VariantInfo<'a> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field5_finish(f, "VariantInfo",
"prefix", &self.prefix, "bindings", &self.bindings, "ast",
&self.ast, "generics", &self.generics, "original_length",
&&self.original_length)
}
}Debug, #[automatically_derived]
impl<'a> ::core::clone::Clone for VariantInfo<'a> {
#[inline]
fn clone(&self) -> VariantInfo<'a> {
VariantInfo {
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: &VariantInfo<'a>) -> 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)]
427pub struct VariantInfo<'a> {
428 pub prefix: Option<&'a Ident>,
429 bindings: Vec<BindingInfo<'a>>,
430 ast: VariantAst<'a>,
431 generics: &'a Generics,
432 original_length: usize,
434}
435
436fn get_ty_params(field: &Field, generics: &Generics) -> Vec<bool> {
440 struct BoundTypeLocator<'a> {
443 result: Vec<bool>,
444 generics: &'a Generics,
445 }
446
447 impl<'a> Visit<'a> for BoundTypeLocator<'a> {
448 fn visit_ident(&mut self, id: &Ident) {
451 for (idx, i) in self.generics.params.iter().enumerate() {
452 if let GenericParam::Type(tparam) = i {
453 if tparam.ident == *id {
454 self.result[idx] = true;
455 }
456 }
457 }
458 }
459
460 fn visit_type_macro(&mut self, x: &'a TypeMacro) {
461 for r in &mut self.result {
464 *r = true;
465 }
466 visit::visit_type_macro(self, x);
467 }
468 }
469
470 let mut btl = BoundTypeLocator {
471 result: ::alloc::vec::from_elem(false, generics.params.len())vec![false; generics.params.len()],
472 generics,
473 };
474
475 btl.visit_type(&field.ty);
476
477 btl.result
478}
479
480impl<'a> VariantInfo<'a> {
481 fn new(ast: VariantAst<'a>, prefix: Option<&'a Ident>, generics: &'a Generics) -> Self {
482 let bindings = match ast.fields {
483 Fields::Unit => ::alloc::vec::Vec::new()vec![],
484 Fields::Unnamed(FieldsUnnamed {
485 unnamed: fields, ..
486 })
487 | Fields::Named(FieldsNamed { named: fields, .. }) => {
488 fields
489 .into_iter()
490 .enumerate()
491 .map(|(i, field)| {
492 let binding_span = Span::call_site().located_at(field.span());
496 BindingInfo {
497 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),
498 style: BindStyle::Ref,
499 field,
500 generics,
501 seen_generics: get_ty_params(field, generics),
502 index: i,
503 }
504 })
505 .collect::<Vec<_>>()
506 }
507 };
508
509 let original_length = bindings.len();
510 VariantInfo {
511 prefix,
512 bindings,
513 ast,
514 generics,
515 original_length,
516 }
517 }
518
519 pub fn bindings(&self) -> &[BindingInfo<'a>] {
521 &self.bindings
522 }
523
524 pub fn bindings_mut(&mut self) -> &mut [BindingInfo<'a>] {
526 &mut self.bindings
527 }
528
529 pub fn ast(&self) -> VariantAst<'a> {
532 self.ast
533 }
534
535 pub fn omitted_bindings(&self) -> bool {
537 self.original_length != self.bindings.len()
538 }
539
540 pub fn pat(&self) -> TokenStream {
561 let mut t = TokenStream::new();
562 if let Some(prefix) = self.prefix {
563 prefix.to_tokens(&mut t);
564 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon2(&mut _s);
_s
}quote!(::).to_tokens(&mut t);
565 }
566 self.ast.ident.to_tokens(&mut t);
567 match self.ast.fields {
568 Fields::Unit => {
569 if !self.bindings.is_empty() {
::core::panicking::panic("assertion failed: self.bindings.is_empty()")
};assert!(self.bindings.is_empty());
570 }
571 Fields::Unnamed(..) => token::Paren(Span::call_site()).surround(&mut t, |t| {
572 let mut expected_index = 0;
573 for binding in &self.bindings {
574 while expected_index < binding.index {
575 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_underscore(&mut _s);
::quote::__private::push_comma(&mut _s);
_s
}quote!(_,).to_tokens(t);
576 expected_index += 1;
577 }
578 binding.pat().to_tokens(t);
579 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_comma(&mut _s);
_s
}quote!(,).to_tokens(t);
580 expected_index += 1;
581 }
582 if expected_index != self.original_length {
583 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_dot2(&mut _s);
_s
}quote!(..).to_tokens(t);
584 }
585 }),
586 Fields::Named(..) => token::Brace(Span::call_site()).surround(&mut t, |t| {
587 for binding in &self.bindings {
588 binding.field.ident.to_tokens(t);
589 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon(&mut _s);
_s
}quote!(:).to_tokens(t);
590 binding.pat().to_tokens(t);
591 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_comma(&mut _s);
_s
}quote!(,).to_tokens(t);
592 }
593 if self.omitted_bindings() {
594 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_dot2(&mut _s);
_s
}quote!(..).to_tokens(t);
595 }
596 }),
597 }
598 t
599 }
600
601 pub fn construct<F, T>(&self, mut func: F) -> TokenStream
634 where
635 F: FnMut(&Field, usize) -> T,
636 T: ToTokens,
637 {
638 let mut t = TokenStream::new();
639 if let Some(prefix) = self.prefix {
640 {
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);
641 }
642 self.ast.ident.to_tokens(&mut t);
643
644 match &self.ast.fields {
645 Fields::Unit => (),
646 Fields::Unnamed(FieldsUnnamed { unnamed, .. }) => {
647 token::Paren::default().surround(&mut t, |t| {
648 for (i, field) in unnamed.into_iter().enumerate() {
649 func(field, i).to_tokens(t);
650 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_comma(&mut _s);
_s
}quote!(,).to_tokens(t);
651 }
652 });
653 }
654 Fields::Named(FieldsNamed { named, .. }) => {
655 token::Brace::default().surround(&mut t, |t| {
656 for (i, field) in named.into_iter().enumerate() {
657 field.ident.to_tokens(t);
658 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_colon(&mut _s);
_s
}quote!(:).to_tokens(t);
659 func(field, i).to_tokens(t);
660 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_comma(&mut _s);
_s
}quote!(,).to_tokens(t);
661 }
662 });
663 }
664 }
665 t
666 }
667
668 pub fn each<F, R>(&self, mut f: F) -> TokenStream
697 where
698 F: FnMut(&BindingInfo<'_>) -> R,
699 R: ToTokens,
700 {
701 let pat = self.pat();
702 let mut body = TokenStream::new();
703 for binding in &self.bindings {
704 token::Brace::default().surround(&mut body, |body| {
705 f(binding).to_tokens(body);
706 });
707 }
708 {
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 })
709 }
710
711 pub fn fold<F, I, R>(&self, init: I, mut f: F) -> TokenStream
740 where
741 F: FnMut(TokenStream, &BindingInfo<'_>) -> R,
742 I: ToTokens,
743 R: ToTokens,
744 {
745 let pat = self.pat();
746 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| {
747 let r = f(i, bi);
748 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&r, &mut _s);
_s
}quote!(#r)
749 });
750 {
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 })
751 }
752
753 pub fn filter<F>(&mut self, f: F) -> &mut Self
791 where
792 F: FnMut(&BindingInfo<'_>) -> bool,
793 {
794 self.bindings.retain(f);
795 self
796 }
797
798 #[allow(clippy::return_self_not_must_use)]
844 pub fn drain_filter<F>(&mut self, mut f: F) -> Self
845 where
846 F: FnMut(&BindingInfo<'_>) -> bool,
847 {
848 let mut other = VariantInfo {
849 prefix: self.prefix,
850 bindings: ::alloc::vec::Vec::new()vec![],
851 ast: self.ast,
852 generics: self.generics,
853 original_length: self.original_length,
854 };
855
856 let (other_bindings, self_bindings) = self.bindings.drain(..).partition(&mut f);
857 other.bindings = other_bindings;
858 self.bindings = self_bindings;
859
860 other
861 }
862
863 pub fn remove_binding(&mut self, idx: usize) -> &mut Self {
869 self.bindings.remove(idx);
870 self
871 }
872
873 pub fn bind_with<F>(&mut self, mut f: F) -> &mut Self
904 where
905 F: FnMut(&BindingInfo<'_>) -> BindStyle,
906 {
907 for binding in &mut self.bindings {
908 binding.style = f(binding);
909 }
910 self
911 }
912
913 pub fn binding_name<F>(&mut self, mut f: F) -> &mut Self
950 where
951 F: FnMut(&Field, usize) -> Ident,
952 {
953 for (it, binding) in self.bindings.iter_mut().enumerate() {
954 binding.binding = f(binding.field, it);
955 }
956 self
957 }
958
959 pub fn referenced_ty_params(&self) -> Vec<&'a Ident> {
985 let mut flags = Vec::new();
986 for binding in &self.bindings {
987 generics_fuse(&mut flags, &binding.seen_generics);
988 }
989 fetch_generics(&flags, self.generics)
990 }
991}
992
993#[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) -> Structure<'a> {
Structure {
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: &Structure<'a>) -> 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)]
996pub struct Structure<'a> {
997 variants: Vec<VariantInfo<'a>>,
998 omitted_variants: bool,
999 ast: &'a DeriveInput,
1000 extra_impl: Vec<GenericParam>,
1001 extra_predicates: Vec<WherePredicate>,
1002 add_bounds: AddBounds,
1003}
1004
1005impl<'a> Structure<'a> {
1006 pub fn new(ast: &'a DeriveInput) -> Self {
1014 Self::try_new(ast).expect("Unable to create synstructure::Structure")
1015 }
1016
1017 pub fn try_new(ast: &'a DeriveInput) -> Result<Self> {
1023 let variants = match &ast.data {
1024 Data::Enum(data) => (&data.variants)
1025 .into_iter()
1026 .map(|v| {
1027 VariantInfo::new(
1028 VariantAst {
1029 attrs: &v.attrs,
1030 ident: &v.ident,
1031 fields: &v.fields,
1032 discriminant: &v.discriminant,
1033 },
1034 Some(&ast.ident),
1035 &ast.generics,
1036 )
1037 })
1038 .collect::<Vec<_>>(),
1039 Data::Struct(data) => {
1040 ::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(
1041 VariantAst {
1042 attrs: &ast.attrs,
1043 ident: &ast.ident,
1044 fields: &data.fields,
1045 discriminant: &None,
1046 },
1047 None,
1048 &ast.generics,
1049 )]
1050 }
1051 Data::Union(_) => {
1052 return Err(Error::new_spanned(
1053 ast,
1054 "unexpected unsupported untagged union",
1055 ));
1056 }
1057 };
1058
1059 Ok(Structure {
1060 variants,
1061 omitted_variants: false,
1062 ast,
1063 extra_impl: ::alloc::vec::Vec::new()vec![],
1064 extra_predicates: ::alloc::vec::Vec::new()vec![],
1065 add_bounds: AddBounds::Both,
1066 })
1067 }
1068
1069 pub fn variants(&self) -> &[VariantInfo<'a>] {
1071 &self.variants
1072 }
1073
1074 pub fn variants_mut(&mut self) -> &mut [VariantInfo<'a>] {
1076 &mut self.variants
1077 }
1078
1079 pub fn ast(&self) -> &'a DeriveInput {
1082 self.ast
1083 }
1084
1085 pub fn omitted_variants(&self) -> bool {
1087 self.omitted_variants
1088 }
1089
1090 pub fn each<F, R>(&self, mut f: F) -> TokenStream
1122 where
1123 F: FnMut(&BindingInfo<'_>) -> R,
1124 R: ToTokens,
1125 {
1126 let mut t = TokenStream::new();
1127 for variant in &self.variants {
1128 variant.each(&mut f).to_tokens(&mut t);
1129 }
1130 if self.omitted_variants {
1131 {
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);
1132 }
1133 t
1134 }
1135
1136 pub fn fold<F, I, R>(&self, init: I, mut f: F) -> TokenStream
1170 where
1171 F: FnMut(TokenStream, &BindingInfo<'_>) -> R,
1172 I: ToTokens,
1173 R: ToTokens,
1174 {
1175 let mut t = TokenStream::new();
1176 for variant in &self.variants {
1177 variant.fold(&init, &mut f).to_tokens(&mut t);
1178 }
1179 if self.omitted_variants {
1180 {
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);
1181 }
1182 t
1183 }
1184
1185 pub fn each_variant<F, R>(&self, mut f: F) -> TokenStream
1220 where
1221 F: FnMut(&VariantInfo<'_>) -> R,
1222 R: ToTokens,
1223 {
1224 let mut t = TokenStream::new();
1225 for variant in &self.variants {
1226 let pat = variant.pat();
1227 let body = f(variant);
1228 {
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);
1229 }
1230 if self.omitted_variants {
1231 {
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);
1232 }
1233 t
1234 }
1235
1236 pub fn filter<F>(&mut self, mut f: F) -> &mut Self
1274 where
1275 F: FnMut(&BindingInfo<'_>) -> bool,
1276 {
1277 for variant in &mut self.variants {
1278 variant.filter(&mut f);
1279 }
1280 self
1281 }
1282
1283 #[allow(clippy::return_self_not_must_use)]
1333 pub fn drain_filter<F>(&mut self, mut f: F) -> Self
1334 where
1335 F: FnMut(&BindingInfo<'_>) -> bool,
1336 {
1337 Self {
1338 variants: self
1339 .variants
1340 .iter_mut()
1341 .map(|variant| variant.drain_filter(&mut f))
1342 .collect(),
1343 omitted_variants: self.omitted_variants,
1344 ast: self.ast,
1345 extra_impl: self.extra_impl.clone(),
1346 extra_predicates: self.extra_predicates.clone(),
1347 add_bounds: self.add_bounds,
1348 }
1349 }
1350
1351 pub fn add_where_predicate(&mut self, pred: WherePredicate) -> &mut Self {
1389 self.extra_predicates.push(pred);
1390 self
1391 }
1392
1393 pub fn add_bounds(&mut self, mode: AddBounds) -> &mut Self {
1431 self.add_bounds = mode;
1432 self
1433 }
1434
1435 pub fn filter_variants<F>(&mut self, f: F) -> &mut Self
1470 where
1471 F: FnMut(&VariantInfo<'_>) -> bool,
1472 {
1473 let before_len = self.variants.len();
1474 self.variants.retain(f);
1475 if self.variants.len() != before_len {
1476 self.omitted_variants = true;
1477 }
1478 self
1479 }
1480 #[allow(clippy::return_self_not_must_use)]
1523 pub fn drain_filter_variants<F>(&mut self, mut f: F) -> Self
1524 where
1525 F: FnMut(&VariantInfo<'_>) -> bool,
1526 {
1527 let mut other = Self {
1528 variants: ::alloc::vec::Vec::new()vec![],
1529 omitted_variants: self.omitted_variants,
1530 ast: self.ast,
1531 extra_impl: self.extra_impl.clone(),
1532 extra_predicates: self.extra_predicates.clone(),
1533 add_bounds: self.add_bounds,
1534 };
1535
1536 let (other_variants, self_variants) = self.variants.drain(..).partition(&mut f);
1537 other.variants = other_variants;
1538 self.variants = self_variants;
1539
1540 other
1541 }
1542
1543 pub fn remove_variant(&mut self, idx: usize) -> &mut Self {
1549 self.variants.remove(idx);
1550 self.omitted_variants = true;
1551 self
1552 }
1553
1554 pub fn bind_with<F>(&mut self, mut f: F) -> &mut Self
1585 where
1586 F: FnMut(&BindingInfo<'_>) -> BindStyle,
1587 {
1588 for variant in &mut self.variants {
1589 variant.bind_with(&mut f);
1590 }
1591 self
1592 }
1593
1594 pub fn binding_name<F>(&mut self, mut f: F) -> &mut Self
1631 where
1632 F: FnMut(&Field, usize) -> Ident,
1633 {
1634 for variant in &mut self.variants {
1635 variant.binding_name(&mut f);
1636 }
1637 self
1638 }
1639
1640 pub fn referenced_ty_params(&self) -> Vec<&'a Ident> {
1668 let mut flags = Vec::new();
1669 for variant in &self.variants {
1670 for binding in &variant.bindings {
1671 generics_fuse(&mut flags, &binding.seen_generics);
1672 }
1673 }
1674 fetch_generics(&flags, &self.ast.generics)
1675 }
1676
1677 pub fn add_impl_generic(&mut self, param: GenericParam) -> &mut Self {
1714 self.extra_impl.push(param);
1715 self
1716 }
1717
1718 pub fn add_trait_bounds(
1727 &self,
1728 bound: &TraitBound,
1729 where_clause: &mut Option<WhereClause>,
1730 mode: AddBounds,
1731 ) {
1732 if !self.extra_predicates.is_empty() {
1734 let clause = get_or_insert_with(&mut *where_clause, || WhereClause {
1735 where_token: Default::default(),
1736 predicates: punctuated::Punctuated::new(),
1737 });
1738 clause
1739 .predicates
1740 .extend(self.extra_predicates.iter().cloned());
1741 }
1742
1743 let mut seen = HashSet::new();
1744 let mut pred = |ty: Type| {
1745 if !seen.contains(&ty) {
1746 seen.insert(ty.clone());
1747
1748 let clause = get_or_insert_with(&mut *where_clause, || WhereClause {
1750 where_token: Default::default(),
1751 predicates: punctuated::Punctuated::new(),
1752 });
1753 clause.predicates.push(WherePredicate::Type(PredicateType {
1754 lifetimes: None,
1755 bounded_ty: ty,
1756 colon_token: Default::default(),
1757 bounds: Some(punctuated::Pair::End(TypeParamBound::Trait(bound.clone())))
1758 .into_iter()
1759 .collect(),
1760 }));
1761 }
1762 };
1763
1764 for variant in &self.variants {
1765 for binding in &variant.bindings {
1766 match mode {
1767 AddBounds::Both | AddBounds::Fields => {
1768 for &seen in &binding.seen_generics {
1769 if seen {
1770 pred(binding.ast().ty.clone());
1771 break;
1772 }
1773 }
1774 }
1775 _ => {}
1776 }
1777
1778 match mode {
1779 AddBounds::Both | AddBounds::Generics => {
1780 for param in binding.referenced_ty_params() {
1781 pred(Type::Path(TypePath {
1782 qself: None,
1783 path: (*param).clone().into(),
1784 }));
1785 }
1786 }
1787 _ => {}
1788 }
1789 }
1790 }
1791 }
1792
1793 pub fn underscore_const(&mut self, _enabled: bool) -> &mut Self {
1795 self
1796 }
1797
1798 pub fn bound_impl<P: ToTokens, B: ToTokens>(&self, path: P, body: B) -> TokenStream {
1858 self.impl_internal(
1859 path.into_token_stream(),
1860 body.into_token_stream(),
1861 ::quote::__private::TokenStream::new()quote!(),
1862 None,
1863 )
1864 }
1865
1866 pub fn unsafe_bound_impl<P: ToTokens, B: ToTokens>(&self, path: P, body: B) -> TokenStream {
1926 self.impl_internal(
1927 path.into_token_stream(),
1928 body.into_token_stream(),
1929 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "unsafe");
_s
}quote!(unsafe),
1930 None,
1931 )
1932 }
1933
1934 pub fn unbound_impl<P: ToTokens, B: ToTokens>(&self, path: P, body: B) -> TokenStream {
1984 self.impl_internal(
1985 path.into_token_stream(),
1986 body.into_token_stream(),
1987 ::quote::__private::TokenStream::new()quote!(),
1988 Some(AddBounds::None),
1989 )
1990 }
1991
1992 #[deprecated]
2042 pub fn unsafe_unbound_impl<P: ToTokens, B: ToTokens>(&self, path: P, body: B) -> TokenStream {
2043 self.impl_internal(
2044 path.into_token_stream(),
2045 body.into_token_stream(),
2046 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "unsafe");
_s
}quote!(unsafe),
2047 Some(AddBounds::None),
2048 )
2049 }
2050
2051 fn impl_internal(
2052 &self,
2053 path: TokenStream,
2054 body: TokenStream,
2055 safety: TokenStream,
2056 mode: Option<AddBounds>,
2057 ) -> TokenStream {
2058 let mode = mode.unwrap_or(self.add_bounds);
2059 let name = &self.ast.ident;
2060 let mut gen_clone = self.ast.generics.clone();
2061 gen_clone.params.extend(self.extra_impl.iter().cloned());
2062 let (impl_generics, _, _) = gen_clone.split_for_impl();
2063 let (_, ty_generics, where_clause) = self.ast.generics.split_for_impl();
2064
2065 let bound = syn::parse2::<TraitBound>(path)
2066 .expect("`path` argument must be a valid rust trait bound");
2067
2068 let mut where_clause = where_clause.cloned();
2069 self.add_trait_bounds(&bound, &mut where_clause, mode);
2070
2071 let mut extern_crate = ::quote::__private::TokenStream::new()quote!();
2076 if bound.path.leading_colon.is_none() {
2077 if let Some(seg) = bound.path.segments.first() {
2078 let seg = &seg.ident;
2079 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; };
2080 }
2081 }
2082
2083 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! {
2084 #extern_crate
2085 #safety impl #impl_generics #bound for #name #ty_generics #where_clause {
2086 #body
2087 }
2088 };
2089
2090 {
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! {
2091 const _: () = { #generated };
2092 }
2093 }
2094
2095 pub fn gen_impl(&self, cfg: TokenStream) -> TokenStream {
2296 Parser::parse2(
2297 |input: ParseStream<'_>| -> Result<TokenStream> { self.gen_impl_parse(input, true) },
2298 cfg,
2299 )
2300 .expect("Failed to parse gen_impl")
2301 }
2302
2303 fn gen_impl_parse(&self, input: ParseStream<'_>, wrap: bool) -> Result<TokenStream> {
2304 fn parse_prefix(input: ParseStream<'_>) -> Result<Option<::syn::token::UnsafeToken![unsafe]>> {
2305 if input.parse::<Ident>()? != "gen" {
2306 return Err(input.error("Expected keyword `gen`"));
2307 }
2308 let safety = input.parse::<Option<::syn::token::UnsafeToken![unsafe]>>()?;
2309 let _ = input.parse::<::syn::token::ImplToken![impl]>()?;
2310 Ok(safety)
2311 }
2312
2313 let mut before = ::alloc::vec::Vec::new()vec![];
2314 loop {
2315 if parse_prefix(&input.fork()).is_ok() {
2316 break;
2317 }
2318 before.push(input.parse::<TokenTree>()?);
2319 }
2320
2321 let safety = parse_prefix(input)?;
2323
2324 let mut generics = input.parse::<Generics>()?;
2326
2327 let bound = input.parse::<TraitBound>()?;
2329
2330 let _ = input.parse::<::syn::token::ForToken![for]>()?;
2332 let _ = input.parse::<::syn::token::AtToken![@]>()?;
2333 let _ = input.parse::<::syn::token::SelfTypeToken![Self]>()?;
2334
2335 generics.where_clause = input.parse()?;
2337
2338 let body;
2340 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);
2341 let body = body.parse::<TokenStream>()?;
2342
2343 let maybe_next_impl = self.gen_impl_parse(&input.fork(), false);
2346
2347 let mut after = input.parse::<TokenStream>()?;
2350 if let Ok(stream) = maybe_next_impl {
2351 after = stream;
2352 }
2353 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");
2354
2355 let name = &self.ast.ident;
2357
2358 if let Err(err) = merge_generics(&mut generics, &self.ast.generics) {
2361 return Ok(err.to_compile_error());
2364 }
2365
2366 self.add_trait_bounds(&bound, &mut generics.where_clause, self.add_bounds);
2367 let (impl_generics, _, where_clause) = generics.split_for_impl();
2368 let (_, ty_generics, _) = self.ast.generics.split_for_impl();
2369
2370 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! {
2371 #(#before)*
2372 #safety impl #impl_generics #bound for #name #ty_generics #where_clause {
2373 #body
2374 }
2375 #after
2376 };
2377
2378 if wrap {
2379 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! {
2380 const _: () = { #generated };
2381 })
2382 } else {
2383 Ok(generated)
2384 }
2385 }
2386}
2387
2388pub fn unpretty_print<T: std::fmt::Display>(ts: T) -> String {
2434 let mut res = String::new();
2435
2436 let raw_s = ts.to_string();
2437 let mut s = &raw_s[..];
2438 let mut indent = 0;
2439 while let Some(i) = s.find(&['(', '{', '[', ')', '}', ']', ';'][..]) {
2440 match &s[i..=i] {
2441 "(" | "{" | "[" => indent += 1,
2442 ")" | "}" | "]" => indent -= 1,
2443 _ => {}
2444 }
2445 res.push_str(&s[..=i]);
2446 res.push('\n');
2447 for _ in 0..indent {
2448 res.push_str(" ");
2449 }
2450 s = trim_start_matches(&s[i + 1..], ' ');
2451 }
2452 res.push_str(s);
2453 res
2454}
2455
2456#[allow(deprecated)]
2460fn trim_start_matches(s: &str, c: char) -> &str {
2461 s.trim_left_matches(c)
2462}
2463
2464pub trait MacroResult {
2467 fn into_result(self) -> Result<TokenStream>;
2469
2470 #[cfg(all(
2479 not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "wasi"))),
2480 feature = "proc-macro"
2481 ))]
2482 fn into_stream(self) -> proc_macro::TokenStream
2483 where
2484 Self: Sized,
2485 {
2486 match self.into_result() {
2487 Ok(ts) => ts.into(),
2488 Err(err) => err.to_compile_error().into(),
2489 }
2490 }
2491}
2492
2493#[cfg(all(
2494 not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "wasi"))),
2495 feature = "proc-macro"
2496))]
2497impl MacroResult for proc_macro::TokenStream {
2498 fn into_result(self) -> Result<TokenStream> {
2499 Ok(self.into())
2500 }
2501
2502 fn into_stream(self) -> proc_macro::TokenStream {
2503 self
2504 }
2505}
2506
2507impl MacroResult for TokenStream {
2508 fn into_result(self) -> Result<TokenStream> {
2509 Ok(self)
2510 }
2511}
2512
2513impl<T: MacroResult> MacroResult for Result<T> {
2514 fn into_result(self) -> Result<TokenStream> {
2515 match self {
2516 Ok(v) => v.into_result(),
2517 Err(err) => Err(err),
2518 }
2519 }
2520}
2521
2522#[cfg(test)]
2523mod tests {
2524 use super::*;
2525
2526 #[test]
2528 fn test_each_enum() {
2529 let di: syn::DeriveInput = syn::parse_quote! {
2530 enum A {
2531 Foo(usize, bool),
2532 Bar(bool, usize),
2533 Baz(usize, bool, usize),
2534 Quux(bool, usize, bool)
2535 }
2536 };
2537 let mut s = Structure::new(&di);
2538
2539 s.filter(|bi| bi.ast().ty.to_token_stream().to_string() == "bool");
2540
2541 assert_eq!(
2542 s.each(|bi| quote!(do_something(#bi))).to_string(),
2543 quote! {
2544 A::Foo(_, ref __binding_1,) => { { do_something(__binding_1) } }
2545 A::Bar(ref __binding_0, ..) => { { do_something(__binding_0) } }
2546 A::Baz(_, ref __binding_1, ..) => { { do_something(__binding_1) } }
2547 A::Quux(ref __binding_0, _, ref __binding_2,) => {
2548 {
2549 do_something(__binding_0)
2550 }
2551 {
2552 do_something(__binding_2)
2553 }
2554 }
2555 }
2556 .to_string()
2557 );
2558 }
2559}