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
impl
declarations. - 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::Generics
to 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 forimpl
blocks, 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_impl
wraps the generics in<>
, which can be limiting when you need to use the generics in a different context or format.decompose
provides raw punctuated generic parameters, offering greater flexibility and control over the output format.decompose
returns 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 )
}
}
}
}