use syn::{punctuated::Punctuated, GenericParam, Generics, PredicateType, Type, TypePath, WherePredicate};
pub fn add_sync_trait_bounds(generics: &mut syn::Generics, contraints: &[&str]) {
generics
.params
.iter_mut()
.filter_map(|param| match param {
syn::GenericParam::Type(ty) => Some(ty),
_ => None,
})
.for_each(|ty| {
add_type_param_bounds(&mut ty.bounds, contraints);
})
}
pub fn add_aggregate_generic_defaults(generics: &mut Generics) {
let new_predicates: Vec<WherePredicate> = generics
.params
.iter()
.filter_map(|param| {
if let GenericParam::Type(ty) = param {
let bounded_ty = Type::Path(TypePath {
qself: None,
path: ty.ident.clone().into(),
});
Some(WherePredicate::Type(PredicateType {
bounded_ty,
colon_token: Default::default(),
bounds: Punctuated::new(),
lifetimes: None,
}))
} else {
None
}
})
.collect();
if !new_predicates.is_empty() {
let where_clause = generics.make_where_clause();
where_clause.predicates.extend(new_predicates);
for predicate in &mut where_clause.predicates {
if let WherePredicate::Type(predicate_type) = predicate {
add_type_param_bounds(&mut predicate_type.bounds, &["Send", "Sync", "'static", "std::fmt::Debug", "Default"]);
}
}
}
}
fn add_type_param_bounds(bounds: &mut Punctuated<syn::TypeParamBound, syn::token::Plus>, new_bounds: &[&str]) {
for bound in new_bounds {
bounds.push(syn::parse_str(bound).unwrap());
}
}