near_lake_context_derive/
lib.rs1#![doc = include_str!("../README.md")]
2use proc_macro::TokenStream;
3use quote::quote;
4
5#[proc_macro_derive(LakeContext)]
6pub fn lake_context_derive(input: TokenStream) -> TokenStream {
7 let input = syn::parse_macro_input!(input as syn::DeriveInput);
8
9 let name = input.ident;
11
12 let fields = if let syn::Data::Struct(syn::DataStruct {
17 fields: syn::Fields::Named(syn::FieldsNamed { named, .. }),
18 ..
19 }) = &input.data
20 {
21 named
22 } else {
23 unimplemented!();
24 };
25
26 let calls_before_run = fields
27 .iter()
28 .filter(|f| {
29 let ty = &f.ty;
30 if let syn::Type::Path(syn::TypePath { path, .. }) = ty {
31 if let Some(ident) = path.get_ident() {
32 ident == "LakeContext"
33 } else {
34 false
35 }
36 } else {
37 false
38 }
39 })
40 .map(|f| {
41 let name = &f.ident;
42 quote! { self.#name.execute_before_run(block); }
43 });
44
45 let calls_after_run = fields
46 .iter()
47 .rev()
48 .filter(|f| {
49 let ty = &f.ty;
50 if let syn::Type::Path(syn::TypePath { path, .. }) = ty {
51 if let Some(ident) = path.get_ident() {
52 ident == "LakeContext"
53 } else {
54 false
55 }
56 } else {
57 false
58 }
59 })
60 .map(|f| {
61 let name = &f.ident;
62 quote! { self.#name.execute_after_run(); }
63 });
64
65 let expanded = quote! {
66 impl near_lake_framework::LakeContextExt for #name {
68 fn execute_before_run(&self, block: &mut near_lake_primitives::block::Block) {
69 #( #calls_before_run )*
70 }
71
72 fn execute_after_run(&self) {
73 #( #calls_after_run )*
74 }
75 }
76 };
77
78 proc_macro::TokenStream::from(expanded)
80}