cgp_component_macro_lib/delegate_components/
delegates_to.rs1use syn::punctuated::Punctuated;
2use syn::token::Plus;
3use syn::{parse_quote, Generics, Ident, ItemImpl, ItemTrait, Type, TypeParamBound};
4
5use crate::delegate_components::ast::DelegateEntriesAst;
6
7pub fn define_delegate_component_trait_bounds(
8 target_type: &Type,
9 delegate_entries: &DelegateEntriesAst,
10) -> Punctuated<TypeParamBound, Plus> {
11 let mut trait_bounds: Punctuated<TypeParamBound, Plus> = Punctuated::new();
12
13 for component in delegate_entries.all_components() {
14 let component_type = &component.component_type;
15 let trait_bound: TypeParamBound = parse_quote!(
16 DelegateComponent<#component_type, Delegate = #target_type>
17 );
18 trait_bounds.push(trait_bound);
19 }
20
21 trait_bounds
22}
23
24pub fn define_delegates_to_trait(
25 trait_name: &Ident,
26 target_type: &Type,
27 target_generics: &Generics,
28 delegate_entries: &DelegateEntriesAst,
29) -> (ItemTrait, ItemImpl) {
30 let trait_bounds = define_delegate_component_trait_bounds(target_type, delegate_entries);
31
32 let item_trait = parse_quote! {
33 pub trait #trait_name #target_generics: #trait_bounds {}
34 };
35
36 let mut impl_generics = target_generics.clone();
37 impl_generics.params.push(parse_quote!(Components));
38
39 let type_generics = target_generics.split_for_impl().1;
40
41 let item_impl = parse_quote! {
42 impl #impl_generics #trait_name #type_generics for Components
43 where
44 Components: #trait_bounds
45 {}
46 };
47
48 (item_trait, item_impl)
49}