kabu_core_actors_macros/
lib.rs1use proc_macro::TokenStream;
2
3use quote::quote;
4use syn::{parse_macro_input, Data, DeriveInput, Field, Fields, PathArguments, Type};
5
6#[proc_macro_derive(Accessor, attributes(accessor))]
7pub fn derive_access(input: TokenStream) -> TokenStream {
8 let input = parse_macro_input!(input as DeriveInput);
9
10 let name = input.ident;
11 let generics = input.generics;
12
13 let data = match input.data {
14 Data::Struct(s) => s,
15 _ => panic!("This macro only works for structs"),
16 };
17
18 let fields = match data.fields {
19 Fields::Named(named) => named,
20 _ => panic!("no named fields"),
21 };
22
23 let mut access_fields: Vec<Field> = Vec::new();
24
25 for field_ in fields.named {
26 for attr in field_.attrs.iter() {
27 if attr.path().is_ident("accessor") {
28 access_fields.push(field_.clone());
29 }
30 }
31 }
32 let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
33
34 let traits = access_fields
35 .into_iter()
36 .map(|field| {
37 let field_name = field.ident.expect("Field needs name");
38 let field_type = match field.ty.clone() {
39 Type::Path(type_path) => match &type_path.path.segments[0].arguments.clone() {
40 PathArguments::AngleBracketed(params) => match ¶ms.args[0] {
41 syn::GenericArgument::Type(ty) => match &ty {
42 Type::Path(type_path) => match &type_path.path.segments[0].arguments.clone() {
43 PathArguments::AngleBracketed(params) => match ¶ms.args[0] {
44 syn::GenericArgument::Type(ty) => ty.clone(),
45 _ => panic!("Expected type parameter"),
46 },
47 _ => panic!("Expected Angle Brackets"),
48 },
49 _ => panic!("Expected DataType parameter"),
50 },
51 _ => panic!("Excpected type parameter"),
52 },
53 _ => panic!("Expected Angle Brackets"),
54 },
55 _ => panic!("Expected Option"),
56 };
57
58 quote! {
59 impl #impl_generics Accessor<#field_type> for #name #ty_generics #where_clause {
60 fn access(&mut self, value : SharedState<#field_type>) -> &mut Self {
61 self.#field_name = Some(value);
62 self
63 }
64 }
65 }
66 })
67 .collect::<Vec<_>>();
68
69 let expanded = quote! {
70 #(#traits)*
71 };
72 expanded.into()
73}
74
75#[proc_macro_derive(Consumer, attributes(consumer))]
76pub fn derive_consumer(input: TokenStream) -> TokenStream {
77 let input = parse_macro_input!(input as DeriveInput);
78
79 let name = input.ident;
80 let generics = input.generics;
81
82 let data = match input.data {
83 Data::Struct(s) => s,
84 _ => panic!("This macro only works for structs"),
85 };
86
87 let fields = match data.fields {
88 Fields::Named(named) => named,
89 _ => panic!("no named fields"),
90 };
91
92 let mut access_fields: Vec<Field> = Vec::new();
93
94 for field_ in fields.named {
95 for attr in field_.attrs.iter() {
96 if attr.path().is_ident("consumer") {
97 access_fields.push(field_.clone());
98 }
99 }
100 }
101 let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
102
103 let traits = access_fields
104 .into_iter()
105 .map(|field| {
106 let field_name = field.ident.expect("Field needs name");
107 let field_type = match field.ty.clone() {
108 Type::Path(type_path) => match &type_path.path.segments[0].arguments.clone() {
109 PathArguments::AngleBracketed(params) => match ¶ms.args[0] {
110 syn::GenericArgument::Type(ty) => match &ty {
111 Type::Path(type_path) => match &type_path.path.segments[0].arguments.clone() {
112 PathArguments::AngleBracketed(params) => match ¶ms.args[0] {
113 syn::GenericArgument::Type(ty) => ty.clone(),
114 _ => panic!("Excpected type parameter"),
115 },
116 _ => panic!("Expected Angle Brackets"),
117 },
118 _ => panic!("Expected DataType parameter"),
119 },
120 _ => panic!("Expected type parameter"),
121 },
122 _ => panic!("Expected Angle Brackets"),
123 },
124 _ => panic!("Expected Option"),
125 };
126
127 quote! {
128 impl #impl_generics Consumer<#field_type> for #name #ty_generics #where_clause {
129 fn consume(&mut self, value : Broadcaster<#field_type>) -> &mut Self {
130 self.#field_name = Some(value);
131 self
132 }
133 }
134 }
135 })
136 .collect::<Vec<_>>();
137
138 let expanded = quote! {
139 #(#traits)*
140 };
141 expanded.into()
142}
143
144#[proc_macro_derive(Producer, attributes(producer))]
145pub fn derive_producer(input: TokenStream) -> TokenStream {
146 let input = parse_macro_input!(input as DeriveInput);
147
148 let name = input.ident;
149 let generics = input.generics;
150
151 let data = match input.data {
152 Data::Struct(s) => s,
153 _ => panic!("This macro only works for structs"),
154 };
155
156 let fields = match data.fields {
157 Fields::Named(named) => named,
158 _ => panic!("no named fields"),
159 };
160
161 let mut access_fields: Vec<Field> = Vec::new();
162
163 for field_ in fields.named {
164 for attr in field_.attrs.iter() {
165 if attr.path().is_ident("producer") {
166 access_fields.push(field_.clone());
167 }
168 }
169 }
170 let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
171
172 let traits = access_fields
173 .into_iter()
174 .map(|field| {
175 let field_name = field.ident.expect("Field needs name");
176 let field_type = match field.ty.clone() {
177 Type::Path(type_path) => match &type_path.path.segments[0].arguments.clone() {
178 PathArguments::AngleBracketed(params) => match ¶ms.args[0] {
179 syn::GenericArgument::Type(ty) => match &ty {
180 Type::Path(type_path) => match &type_path.path.segments[0].arguments.clone() {
181 PathArguments::AngleBracketed(params) => match ¶ms.args[0] {
182 syn::GenericArgument::Type(ty) => ty.clone(),
183 _ => panic!("Expected type parameter"),
184 },
185 _ => panic!("Expected Angle Brackets"),
186 },
187 _ => panic!("Expected DataType parameter"),
188 },
189 _ => panic!("Excected type parameter"),
190 },
191 _ => panic!("Expected Angle Brackets"),
192 },
193 _ => panic!("Expected Option"),
194 };
195
196 quote! {
197 impl #impl_generics Producer<#field_type> for #name #ty_generics #where_clause {
198 fn produce(&mut self, value : Broadcaster<#field_type>) -> &mut Self {
199 self.#field_name = Some(value);
200 self
201 }
202 }
203 }
204 })
205 .collect::<Vec<_>>();
206
207 let expanded = quote! {
208 #(#traits)*
209 };
210
211 expanded.into()
212}