Function macro_tools::generic_params::decompose
source · pub fn decompose(
generics: &Generics,
) -> (Punctuated<GenericParam, Comma>, Punctuated<GenericParam, Comma>, Punctuated<GenericParam, Comma>, Punctuated<WherePredicate, Comma>)Expand description
Decomposes syn::Generics into components suitable for different usage contexts in Rust implementations,
specifically focusing on different requirements for impl blocks and type definitions.
This function prepares three versions of the generics:
- One preserving the full structure for
impldeclarations. - One simplified for type definitions, removing bounds and defaults from type and const parameters, retaining only identifiers.
- One for the where clauses, if present, ensuring they are correctly punctuated.
This helps in situations where you need different representations of generics for implementing traits, defining types, or specifying trait bounds and conditions.
This function is similar to syn::Generics::split_for_impl, which also splits generics into components
suitable for impl blocks and type definitions. However, split_for_impl wraps the tokens in <>, which
can reduce the flexibility of the results. The decompose function provides more control over the output
by not wrapping the tokens, allowing for more precise usage in macros and other contexts.
Additionally, decompose returns an extra component with the generics including defaults, which is often
in demand for certain macro or code generation tasks.
§Examples
let code : syn::Generics = syn::parse_quote!{ <'a, T, const N : usize, U : Trait1> };
let ( generics_with_defaults, generics_for_impl, generics_for_ty, generics_where ) = macro_tools::generic_params::decompose( &code );
// Use in a macro for generating code
macro_tools::qt!
{
impl < #generics_for_impl > MyTrait for Struct1 < #generics_for_ty >
where
#generics_where
{
// implementation details...
}
};§Arguments
generics- A reference to thesyn::Genericsto be decomposed.
§Returns
Returns a tuple containing:
syn::punctuated::Punctuated<syn::GenericParam, syn::token::Comma>: Original generics with defaults, used where full specification is needed.syn::punctuated::Punctuated<syn::GenericParam, syn::token::Comma>: Generics forimplblocks, retaining bounds but no defaults.syn::punctuated::Punctuated<syn::GenericParam, syn::token::Comma>: Simplified generics for type definitions, only identifiers.syn::punctuated::Punctuated<syn::WherePredicate, syn::token::Comma>: Where clauses, properly punctuated for use in where conditions.
§Differences from syn::Generics::split_for_impl
While both decompose and split_for_impl functions split generics into components for impl blocks, type definitions, and where clauses,
there are key differences:
split_for_implwraps the generics in<>, which can be limiting when you need to use the generics in a different context or format.decomposeprovides raw punctuated generic parameters, offering greater flexibility and control over the output format.decomposereturns an extra component with the generics including defaults, which is often needed for certain macro or code generation tasks.
§Example of function signature using decompose
use macro_tools::{ syn, proc_macro2, qt };
fn generate_unit
(
item_name : &syn::Ident,
generics_with_defaults : syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >,
generics_impl : syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >,
generics_ty : syn::punctuated::Punctuated< syn::GenericParam, syn::token::Comma >,
generics_where: syn::punctuated::Punctuated< syn::WherePredicate, syn::token::Comma >,
)
-> proc_macro2::TokenStream
{
qt!
{
#[ automatically_derived ]
impl< #generics_impl > From< i32 > for #item_name< #generics_ty >
where
#generics_where
{
#[ inline ]
fn from( src : i32 ) -> Self
{
Wrap( src )
}
}
}
}