yew_macro/derive_props/
generics.rs1use proc_macro2::Ident;
2use syn::punctuated::Punctuated;
3use syn::{GenericArgument, GenericParam, Generics, Path, Token, Type, TypePath};
4
5pub type GenericArguments = Punctuated<GenericArgument, Token![,]>;
7
8fn first_default_or_const_param_position(generics: &Generics) -> Option<usize> {
10 generics.params.iter().position(|param| match param {
11 GenericParam::Type(param) => param.default.is_some(),
12 GenericParam::Const(_) => true,
13 _ => false,
14 })
15}
16
17pub fn push_type_param(generics: &mut Generics, type_param: GenericParam) {
19 if let Some(idx) = first_default_or_const_param_position(generics) {
20 generics.params.insert(idx, type_param)
21 } else {
22 generics.params.push(type_param)
23 }
24}
25
26pub fn to_arguments(generics: &Generics) -> GenericArguments {
28 let mut args: GenericArguments = Punctuated::new();
29 args.extend(generics.params.iter().map(|param| match param {
30 GenericParam::Type(type_param) => new_generic_type_arg(type_param.ident.clone()),
31 GenericParam::Lifetime(lifetime_param) => {
32 GenericArgument::Lifetime(lifetime_param.lifetime.clone())
33 }
34 GenericParam::Const(const_param) => new_generic_type_arg(const_param.ident.clone()),
35 }));
36 args
37}
38
39fn new_generic_type_arg(ident: Ident) -> GenericArgument {
41 GenericArgument::Type(Type::Path(TypePath {
42 path: Path::from(ident),
43 qself: None,
44 }))
45}