cgp_component_macro_lib/delegate_components/
ast.rs1use core::iter;
2
3use proc_macro2::TokenStream;
4use quote::ToTokens;
5use syn::parse::{Parse, ParseStream};
6use syn::punctuated::Punctuated;
7use syn::token::{Bracket, Colon, Comma, Lt};
8use syn::{braced, bracketed, Generics, Token, Type};
9
10pub struct DelegateComponentsAst {
11 pub target_type: Type,
12 pub target_generics: Generics,
13 pub delegate_entries: DelegateEntriesAst,
14}
15
16pub struct DelegateEntriesAst {
17 pub entries: Punctuated<DelegateEntryAst, Comma>,
18}
19
20pub struct DelegateEntryAst {
21 pub components: Punctuated<ComponentAst, Comma>,
22 pub source: Type,
23}
24
25#[derive(Clone)]
26pub struct ComponentAst {
27 pub component_type: Type,
28 pub component_generics: Generics,
29}
30
31impl DelegateEntriesAst {
32 pub fn all_components(&self) -> Punctuated<ComponentAst, Comma> {
33 self.entries
34 .iter()
35 .flat_map(|entry| entry.components.clone().into_iter())
36 .collect()
37 }
38}
39
40impl Parse for DelegateComponentsAst {
41 fn parse(input: ParseStream) -> syn::Result<Self> {
42 let target_generics = if input.peek(Lt) {
43 input.parse()?
44 } else {
45 Default::default()
46 };
47
48 let target_type: Type = input.parse()?;
49
50 let delegate_entries: DelegateEntriesAst = input.parse()?;
51
52 Ok(Self {
53 target_type,
54 target_generics,
55 delegate_entries,
56 })
57 }
58}
59
60impl Parse for DelegateEntriesAst {
61 fn parse(input: ParseStream) -> syn::Result<Self> {
62 let entries = {
63 let entries_body;
64 braced!(entries_body in input);
65 entries_body.parse_terminated(DelegateEntryAst::parse, Comma)?
66 };
67
68 Ok(Self { entries })
69 }
70}
71
72impl Parse for DelegateEntryAst {
73 fn parse(input: ParseStream) -> syn::Result<Self> {
74 let components = if input.peek(Bracket) {
75 let components_body;
76 bracketed!(components_body in input);
77 components_body.parse_terminated(ComponentAst::parse, Token![,])?
78 } else {
79 let component: ComponentAst = input.parse()?;
80 Punctuated::from_iter(iter::once(component))
81 };
82
83 let _: Colon = input.parse()?;
84
85 let source: Type = input.parse()?;
86
87 Ok(Self { components, source })
88 }
89}
90
91impl Parse for ComponentAst {
92 fn parse(input: ParseStream) -> syn::Result<Self> {
93 let component_generics = if input.peek(Lt) {
94 input.parse()?
95 } else {
96 Default::default()
97 };
98
99 let component_type: Type = input.parse()?;
100
101 Ok(Self {
102 component_type,
103 component_generics,
104 })
105 }
106}
107
108impl ToTokens for ComponentAst {
109 fn to_tokens(&self, tokens: &mut TokenStream) {
110 tokens.extend(self.component_generics.to_token_stream());
111 tokens.extend(self.component_type.to_token_stream());
112 }
113}