cgp_component_macro_lib/delegate_components/
delegates_to.rs

1use 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}