1#![recursion_limit = "512"]
14
15extern crate proc_macro;
16
17use proc_macro::TokenStream;
18use quote::{quote, quote_spanned};
19use syn::spanned::Spanned;
20
21#[cfg(not(test))] #[proc_macro_attribute]
33pub fn main(_attr: TokenStream, item: TokenStream) -> TokenStream {
34 let input = syn::parse_macro_input!(item as syn::ItemFn);
35
36 let ret = &input.sig.output;
37 let inputs = &input.sig.inputs;
38 let name = &input.sig.ident;
39 let body = &input.block;
40 let attrs = &input.attrs;
41
42 if name != "main" {
43 return TokenStream::from(quote_spanned! { name.span() =>
44 compile_error!("only the main function can be tagged with #[kayrx::main]"),
45 });
46 }
47
48 if input.sig.asyncness.is_none() {
49 return TokenStream::from(quote_spanned! { input.span() =>
50 compile_error!("the async keyword is missing from the function declaration"),
51 });
52 }
53
54 let result = quote! {
55 fn main() #ret {
56 #(#attrs)*
57 async fn main(#inputs) #ret {
58 #body
59 }
60
61 kayrx::karx::exec(async {
62 main().await
63 })
64 }
65
66 };
67
68 result.into()
69}
70
71#[proc_macro_attribute]
83pub fn test(_attr: TokenStream, item: TokenStream) -> TokenStream {
84 let input = syn::parse_macro_input!(item as syn::ItemFn);
85
86 let ret = &input.sig.output;
87 let name = &input.sig.ident;
88 let body = &input.block;
89 let attrs = &input.attrs;
90
91 if input.sig.asyncness.is_none() {
92 return TokenStream::from(quote_spanned! { input.span() =>
93 compile_error!("the async keyword is missing from the function declaration"),
94 });
95 }
96
97 let result = quote! {
98 #[test]
99 #(#attrs)*
100 fn #name() #ret {
101 kayrx::karx::exec(async { #body })
102 }
103 };
104
105 result.into()
106}
107
108
109#[proc_macro_attribute]
120pub fn futures(_attr: TokenStream, item: TokenStream) -> TokenStream {
121 let input = syn::parse_macro_input!(item as syn::ItemFn);
122
123 let ret = &input.sig.output;
124 let inputs = &input.sig.inputs;
125 let name = &input.sig.ident;
126 let body = &input.block;
127 let attrs = &input.attrs;
128
129 if name != "main" {
130 return TokenStream::from(quote_spanned! { name.span() =>
131 compile_error!("only the main function can be tagged with #[kayrx::futures]"),
132 });
133 }
134
135 if input.sig.asyncness.is_none() {
136 return TokenStream::from(quote_spanned! { input.span() =>
137 compile_error!("the futures async keyword is missing from the function declaration"),
138 });
139 }
140
141 let result = quote! {
142 fn main() #ret {
143 #(#attrs)*
144 async fn main(#inputs) #ret {
145 #body
146 }
147
148 kayrx::karx::futures::default().exec(async {
149 main().await
150 })
151 }
152
153 };
154
155 result.into()
156}