cgp_macro_lib/entrypoints/
delegate_and_check_components.rs1use proc_macro2::{Span, TokenStream};
2use quote::{ToTokens, TokenStreamExt};
3use syn::punctuated::Punctuated;
4use syn::spanned::Spanned;
5use syn::token::{Comma, Where};
6use syn::{Type, WhereClause, parse2};
7
8use crate::check_components::derive_check_components;
9use crate::delegate_components::impl_delegate_components;
10use crate::parse::{
11 CheckComponents, CheckEntries, CheckEntry, DelegateAndCheckSpec, DelegateEntry, DelegateKey,
12 DelegateValue, ImplGenerics,
13};
14
15pub fn delegate_and_check_components(body: TokenStream) -> syn::Result<TokenStream> {
16 let spec: DelegateAndCheckSpec = parse2(body)?;
17
18 let check_entries: Vec<CheckEntry> = spec
19 .entries
20 .iter()
21 .flat_map(|entry| {
22 entry.keys.iter().map(|component_type| {
23 let span = component_type.span();
24
25 CheckEntry {
26 component_type: component_type.clone(),
27 component_params: None,
28 span,
29 }
30 })
31 })
32 .collect();
33
34 let delegate_entries: Punctuated<DelegateEntry<Type>, Comma> = spec
35 .entries
36 .into_iter()
37 .map(|entry| {
38 let keys = entry
39 .keys
40 .into_iter()
41 .map(|ty| DelegateKey {
42 ty,
43 generics: ImplGenerics::default(),
44 })
45 .collect();
46
47 let value = DelegateValue::Type(entry.value);
48
49 DelegateEntry {
50 keys,
51 value,
52 mode: entry.mode,
53 }
54 })
55 .collect();
56
57 let mut out =
58 impl_delegate_components(&spec.provider_type, &spec.impl_generics, &delegate_entries)?;
59
60 let check_spec = CheckComponents {
61 impl_generics: spec.impl_generics,
62 trait_name: spec.trait_name,
63 context_type: spec.context_type,
64 where_clause: WhereClause {
65 where_token: Where(Span::call_site()),
66 predicates: Punctuated::default(),
67 },
68 check_entries: CheckEntries {
69 entries: check_entries,
70 },
71 };
72
73 let (check_item_trait, check_item_impls) = derive_check_components(&check_spec)?;
74
75 out.extend(check_item_trait.to_token_stream());
76 out.append_all(check_item_impls);
77
78 Ok(out)
79}