kioto_uring_executor_macros/
lib.rs1extern crate proc_macro;
2
3use proc_macro::TokenStream;
4use quote::quote;
5use syn::ItemFn;
6
7fn token_stream_with_error(mut tokens: TokenStream, error: syn::Error) -> TokenStream {
8 tokens.extend(TokenStream::from(error.into_compile_error()));
9 tokens
10}
11
12#[proc_macro_attribute]
13pub fn test(_args: TokenStream, item: TokenStream) -> TokenStream {
14 let mut input: ItemFn = match syn::parse2(item.clone().into()) {
15 Ok(it) => it,
16 Err(e) => return token_stream_with_error(item, e),
17 };
18
19 if input.sig.asyncness.is_none() {
20 panic!("the `async` keyword is missing from the test declaration");
21 }
22
23 input.sig.asyncness = None;
24
25 let body = &input.block;
26 let brace_token = input.block.brace_token;
27
28 let header = quote! {
29 #[::core::prelude::v1::test]
30 };
31
32 let tokio_expr = quote! {
33 let runtime = kioto_uring_executor::Runtime::new();
34 unsafe {
35 runtime.unsafe_block_on(async {
36 #body
37 })
38 }
39 };
40
41 input.block = syn::parse2(quote! {
42 {
43 #tokio_expr
44 }
45 })
46 .expect("Parsing failure");
47 input.block.brace_token = brace_token;
48
49 let result = quote! {
50 #header
51 #input
52 };
53
54 result.into()
55}
56
57#[proc_macro_attribute]
58pub fn main(_args: TokenStream, item: TokenStream) -> TokenStream {
59 let mut input: ItemFn = match syn::parse2(item.clone().into()) {
60 Ok(it) => it,
61 Err(e) => return token_stream_with_error(item, e),
62 };
63
64 if input.sig.asyncness.is_none() {
65 panic!("the `async` keyword is missing from the main function declaration");
66 }
67
68 if input.sig.ident != "main" {
69 panic!("Main function must be called `main`");
70 }
71
72 input.sig.asyncness = None;
73
74 let body = &input.block;
75 let brace_token = input.block.brace_token;
76
77 let tokio_expr = quote! {
78 unsafe {
79 let runtime = kioto_uring_executor::Runtime::new();
80 runtime.unsafe_block_on(async {
81 #body
82 })
83 }
84 };
85
86 input.block = syn::parse2(quote! {
87 {
88 #tokio_expr
89 }
90 })
91 .expect("Parsing failure");
92 input.block.brace_token = brace_token;
93
94 quote! {
95 #input
96 }
97 .into()
98}