pub mod classification;
pub mod filter;
pub mod combine;
mod private
{
use crate :: *;
#[ derive( Debug ) ]
pub struct GenericsWithWhere
{
pub generics: syn ::Generics,
}
impl GenericsWithWhere
{
#[ must_use ]
pub fn unwrap(self) -> syn ::Generics
{
self.generics
}
pub fn parse_from_str(s: &str) -> syn ::Result< GenericsWithWhere >
{
syn ::parse_str :: < GenericsWithWhere >(s)
}
}
impl syn ::parse ::Parse for GenericsWithWhere
{
fn parse(input: syn ::parse ::ParseStream< '_ >) -> syn ::Result< Self >
{
let generics: syn ::Generics = input.parse()?;
let where_clause: Option< syn ::WhereClause > = input.parse()?;
let mut generics_clone = generics.clone();
generics_clone.where_clause = where_clause;
Ok(GenericsWithWhere {
generics: generics_clone,
})
}
}
impl quote ::ToTokens for GenericsWithWhere
{
fn to_tokens(&self, tokens: &mut proc_macro2 ::TokenStream)
{
self.generics.to_tokens(tokens);
}
}
impl From< GenericsWithWhere > for syn ::Generics
{
fn from(g: GenericsWithWhere) -> Self
{
g.generics
}
}
impl From< syn ::Generics > for GenericsWithWhere
{
fn from(generics: syn ::Generics) -> Self
{
GenericsWithWhere { generics }
}
}
#[ derive( Debug, Clone, Copy ) ]
pub struct GenericsRef< 'a >
{
syn_generics: &'a syn ::Generics,
}
impl< 'a > GenericsRef< 'a >
{
#[ must_use ]
pub fn new_borrowed(syn_generics: &'a syn ::Generics) -> Self
{
Self { syn_generics }
}
#[ must_use ]
pub fn new(syn_generics: &'a syn ::Generics) -> Self
{
Self ::new_borrowed(syn_generics)
}
#[ must_use ]
pub fn impl_generics_tokens_if_any( &self ) -> proc_macro2 ::TokenStream
{
if self.syn_generics.params.is_empty()
{
return quote ::quote! {};
}
let (impl_g, _, _) = self.syn_generics.split_for_impl();
quote ::quote! { #impl_g }
}
#[ must_use ]
pub fn ty_generics_tokens_if_any( &self ) -> proc_macro2 ::TokenStream
{
if self.syn_generics.params.is_empty()
{
return quote ::quote! {};
}
let (_, ty_g, _) = self.syn_generics.split_for_impl();
quote ::quote! { #ty_g }
}
#[ must_use ]
pub fn where_clause_tokens_if_any( &self ) -> proc_macro2 ::TokenStream
{
let (_, _, where_clause) = self.syn_generics.split_for_impl();
quote ::quote! { #where_clause }
}
#[ must_use ]
pub fn type_path_tokens_if_any(&self, base_ident: &syn ::Ident) -> proc_macro2 ::TokenStream
{
if self.syn_generics.params.is_empty()
{
quote ::quote! { #base_ident }
}
else
{
let (_, ty_g, _) = self.syn_generics.split_for_impl();
quote ::quote! { #base_ident #ty_g }
}
}
#[ must_use ]
pub fn classification( &self ) -> super ::classification ::GenericsClassification< 'a >
{
super ::classification ::classify_generics(self.syn_generics)
}
#[ must_use ]
pub fn impl_generics_no_lifetimes( &self ) -> proc_macro2 ::TokenStream
{
let filtered = super ::filter ::filter_params(&self.syn_generics.params, super ::filter ::filter_non_lifetimes);
if filtered.is_empty()
{
quote ::quote! {}
} else {
quote ::quote! { < #filtered > }
}
}
#[ must_use ]
pub fn ty_generics_no_lifetimes( &self ) -> proc_macro2 ::TokenStream
{
let (_, _, ty_params, _) = crate::generic_params::decompose(self.syn_generics);
let filtered = super ::filter ::filter_params(&ty_params, super ::filter ::filter_non_lifetimes);
if filtered.is_empty()
{
quote ::quote! {}
} else {
quote ::quote! { < #filtered > }
}
}
#[ must_use ]
pub fn has_only_lifetimes( &self ) -> bool
{
self.classification().has_only_lifetimes
}
#[ must_use ]
pub fn has_only_types( &self ) -> bool
{
self.classification().has_only_types
}
#[ must_use ]
pub fn has_only_consts( &self ) -> bool
{
self.classification().has_only_consts
}
#[ must_use ]
pub fn type_path_no_lifetimes(&self, base_ident: &syn ::Ident) -> proc_macro2 ::TokenStream
{
let ty_no_lifetimes = self.ty_generics_no_lifetimes();
if self.syn_generics.params.is_empty() ||
self.syn_generics.params.iter().all(|p| matches!(p, syn ::GenericParam ::Lifetime(_))) {
quote ::quote! { #base_ident }
} else {
quote ::quote! { #base_ident #ty_no_lifetimes }
}
}
}
}
#[ must_use ]
#[ allow( clippy ::default_trait_access ) ]
pub fn merge(a: &syn ::Generics, b: &syn ::Generics) -> syn ::Generics
{
let mut result = syn ::Generics {
params: Default ::default(),
where_clause: None,
lt_token: Some(syn ::token ::Lt ::default()),
gt_token: Some(syn ::token ::Gt ::default()),
};
for param in &a.params
{
result.params.push(param.clone());
}
for param in &b.params
{
result.params.push(param.clone());
}
result.where_clause = match (&a.where_clause, &b.where_clause)
{
(Some(a_clause), Some(b_clause)) =>
{
let mut merged_where_clause = syn ::WhereClause {
where_token: a_clause.where_token,
predicates: a_clause.predicates.clone(),
};
for predicate in &b_clause.predicates
{
merged_where_clause.predicates.push(predicate.clone());
}
Some(merged_where_clause)
}
(Some(a_clause), None) => Some(a_clause.clone()),
(None, Some(b_clause)) => Some(b_clause.clone()),
_ => None,
};
result
}
#[ allow( clippy ::default_trait_access ) ]
#[ must_use ]
pub fn only_names(generics: &syn ::Generics) -> syn ::Generics
{
use syn :: { Generics, GenericParam, LifetimeParam, TypeParam, ConstParam };
let params = generics
.params
.iter()
.map(|param| match param {
GenericParam::Type(TypeParam { ident, .. }) => GenericParam::Type(TypeParam {
attrs: Vec::new(),
ident: ident.clone(),
colon_token: None,
bounds: Default::default(),
eq_token: None,
default: None,
}),
GenericParam::Lifetime(LifetimeParam { lifetime, .. }) => GenericParam::Lifetime(LifetimeParam {
attrs: Vec::new(),
lifetime: lifetime.clone(),
colon_token: None,
bounds: Default::default(),
}),
GenericParam::Const(ConstParam { ident, ty, .. }) => GenericParam::Const(ConstParam {
attrs: Vec::new(),
const_token: Default::default(),
ident: ident.clone(),
colon_token: Default::default(),
ty: ty.clone(),
eq_token: Default::default(),
default: None,
}),
})
.collect();
Generics {
params,
where_clause: None,
lt_token: generics.lt_token,
gt_token: generics.gt_token,
}
}
pub fn names(generics: &syn ::Generics) -> impl Iterator< Item = &syn ::Ident >
{
generics.params.iter().map( |param| match param
{
syn ::GenericParam ::Type(type_param) => &type_param.ident,
syn ::GenericParam ::Lifetime(lifetime_def) => &lifetime_def.lifetime.ident,
syn ::GenericParam ::Const(const_param) => &const_param.ident,
} )
}
#[ allow( clippy ::type_complexity ) ]
#[ allow( clippy ::too_many_lines ) ]
#[ must_use ]
pub fn decompose(
generics: &syn ::Generics,
) -> (
syn ::punctuated ::Punctuated< syn ::GenericParam, syn ::token ::Comma >,
syn ::punctuated ::Punctuated< syn ::GenericParam, syn ::token ::Comma >,
syn ::punctuated ::Punctuated< syn ::GenericParam, syn ::token ::Comma >,
syn ::punctuated ::Punctuated< syn ::WherePredicate, syn ::token ::Comma >,
) {
let mut generics_with_defaults = generics.params.clone();
crate::punctuated ::ensure_trailing_comma(&mut generics_with_defaults);
let mut generics_for_impl = syn ::punctuated ::Punctuated ::new();
let mut generics_for_ty = syn ::punctuated ::Punctuated ::new();
let params_count = generics.params.len();
for (idx, param) in generics.params.iter().enumerate()
{
let is_last = idx == params_count - 1;
match param
{
syn ::GenericParam ::Type(type_param) =>
{
let impl_param = syn ::GenericParam ::Type(syn ::TypeParam {
attrs: vec![],
ident: type_param.ident.clone(),
colon_token: type_param.colon_token,
bounds: type_param.bounds.clone(),
eq_token: None, default: None, });
generics_for_impl.push_value(impl_param);
if !is_last
{
generics_for_impl.push_punct(syn ::token ::Comma ::default());
}
let ty_param = syn ::GenericParam ::Type(syn ::TypeParam {
attrs: vec![],
ident: type_param.ident.clone(),
colon_token: None,
bounds: syn ::punctuated ::Punctuated ::new(),
eq_token: None,
default: None,
});
generics_for_ty.push_value(ty_param);
if !is_last
{
generics_for_ty.push_punct(syn ::token ::Comma ::default());
}
}
syn ::GenericParam ::Const(const_param) =>
{
let impl_param = syn ::GenericParam ::Const(syn ::ConstParam {
attrs: vec![],
const_token: const_param.const_token,
ident: const_param.ident.clone(),
colon_token: const_param.colon_token,
ty: const_param.ty.clone(),
eq_token: None,
default: None,
});
generics_for_impl.push_value(impl_param);
if !is_last
{
generics_for_impl.push_punct(syn ::token ::Comma ::default());
}
let ty_param = syn ::GenericParam ::Const(syn ::ConstParam {
attrs: vec![],
const_token: const_param.const_token,
ident: const_param.ident.clone(),
colon_token: const_param.colon_token,
ty: const_param.ty.clone(),
eq_token: None,
default: None,
});
generics_for_ty.push_value(ty_param);
if !is_last
{
generics_for_ty.push_punct(syn ::token ::Comma ::default());
}
}
syn ::GenericParam ::Lifetime(lifetime_param) =>
{
generics_for_impl.push_value(syn ::GenericParam ::Lifetime(lifetime_param.clone()));
if !is_last
{
generics_for_impl.push_punct(syn ::token ::Comma ::default());
}
let ty_param = syn ::GenericParam ::Lifetime(syn ::LifetimeParam {
attrs: vec![],
lifetime: lifetime_param.lifetime.clone(),
colon_token: None,
bounds: syn ::punctuated ::Punctuated ::new(),
});
generics_for_ty.push_value(ty_param);
if !is_last
{
generics_for_ty.push_punct(syn ::token ::Comma ::default());
}
}
}
}
while generics_for_impl.trailing_punct()
{
generics_for_impl.pop_punct();
}
while generics_for_ty.trailing_punct()
{
generics_for_ty.pop_punct();
}
let generics_where = if let Some(where_clause) = &generics.where_clause
{
let mut predicates = where_clause.predicates.clone();
crate::punctuated ::ensure_trailing_comma(&mut predicates);
predicates
} else {
syn ::punctuated ::Punctuated ::new()
};
(generics_with_defaults, generics_for_impl, generics_for_ty, generics_where)
}
#[ doc( inline ) ]
#[ allow( unused_imports ) ]
pub use own :: *;
#[ allow( unused_imports ) ]
pub mod own
{
use super :: *;
#[ doc( inline ) ]
pub use orphan :: *;
#[ doc( inline ) ]
pub use crate::generic_params::private :: {
GenericsRef, GenericsWithWhere,
};
pub use super::{ merge, only_names, names, decompose };
#[ doc( inline ) ]
pub use crate::generic_params::classification :: {
GenericsClassification, classify_generics,
DecomposedClassified, decompose_classified,
};
#[ doc( inline ) ]
pub use crate::generic_params::filter :: {
filter_params,
filter_lifetimes, filter_types, filter_consts, filter_non_lifetimes,
};
#[ doc( inline ) ]
pub use crate::generic_params::combine :: {
merge_params_ordered, params_with_additional, params_from_components,
};
}
#[ allow( unused_imports ) ]
pub mod orphan
{
use super :: *;
#[ doc( inline ) ]
pub use exposed :: *;
}
#[ allow( unused_imports ) ]
pub mod exposed
{
use super :: *;
pub use crate::generic_params;
#[ doc( inline ) ]
pub use prelude :: *;
}
#[ allow( unused_imports ) ]
pub mod prelude
{
use super :: *;
}