executor_macros/
lib.rs

1extern crate alloc;
2#[allow(unused_extern_crates)]
3extern crate proc_macro;
4use alloc::str::FromStr;
5use proc_macro::{Delimiter, TokenStream, TokenTree};
6
7#[proc_macro_attribute]
8pub fn entry(_args: TokenStream, item: TokenStream) -> TokenStream {
9    let mut input = item.into_iter().peekable();
10    let mut saw_pub = false;
11    if let Some(TokenTree::Ident(t)) = input.next() {
12        if t.to_string() == "pub" {
13            saw_pub = true;
14        } else if t.to_string() != "async" {
15            panic!("Expected \"async\"")
16        }
17    } else {
18        panic!("Expected \"async\"")
19    }
20
21    if saw_pub {
22        if let Some(TokenTree::Ident(t)) = input.next() {
23            if t.to_string() != "async" {
24                panic!("Expected \"async\"")
25            }
26        } else {
27            panic!("Expected \"async\"")
28        }
29    }
30
31    if let Some(TokenTree::Ident(t)) = input.next() {
32        if t.to_string() != "fn" {
33            panic!("Expected \"fn\"")
34        }
35    } else {
36        panic!("Expected \"fn\"")
37    }
38    let function_name = if let Some(TokenTree::Ident(t)) = input.next() {
39        t.to_string()
40    } else {
41        panic!("Expected function name")
42    };
43    let func_params = if let Some(TokenTree::Group(t)) = input.next() {
44        if t.delimiter() == Delimiter::Parenthesis {
45            t.stream().to_string()
46        } else {
47            panic!("Expected function paramters")
48        }
49    } else {
50        panic!("Expected function paramters")
51    };
52    let function_content = if let Some(TokenTree::Group(t)) = input.next() {
53        if t.delimiter() == Delimiter::Brace {
54            t.stream().to_string()
55        } else {
56            panic!("Expected function content")
57        }
58    } else {
59        panic!("Expected function content")
60    };
61    let func = &format!(
62        "fn {}({}) {{
63        executor::block_on(async move{{ 
64            {}   
65       }})
66    }}",
67        function_name, func_params, function_content
68    );
69    TokenStream::from_str(func).unwrap()
70}
71
72#[proc_macro_attribute]
73pub fn main(_args: TokenStream, item: TokenStream) -> TokenStream {
74    let mut input = item.into_iter().peekable();
75    let mut saw_pub = false;
76    if let Some(TokenTree::Ident(t)) = input.next() {
77        if t.to_string() == "pub" {
78            saw_pub = true;
79        } else if t.to_string() != "async" {
80            panic!("Expected \"pub\" or \"async\"")
81        }
82    } else {
83        panic!("Expected \"async\"")
84    }
85
86    if saw_pub {
87        if let Some(TokenTree::Ident(t)) = input.next() {
88            if t.to_string() != "async" {
89                panic!("Expected \"async\"")
90            }
91        } else {
92            panic!("Expected \"async\"")
93        }
94    }
95    if let Some(TokenTree::Ident(t)) = input.next() {
96        if t.to_string() != "fn" {
97            panic!("Expected \"fn\"")
98        }
99    } else {
100        panic!("Expected \"fn\"")
101    }
102    if let Some(TokenTree::Ident(t)) = input.next() {
103        let s = t.to_string();
104        if s != "main" {
105            panic!("Expected \"main\"")
106        }
107    } else {
108        panic!("Expected function name")
109    }
110    let func_params = if let Some(TokenTree::Group(t)) = input.next() {
111        if t.delimiter() == Delimiter::Parenthesis {
112            t.stream().to_string()
113        } else {
114            panic!("Expected function paramters")
115        }
116    } else {
117        panic!("Expected function paramters")
118    };
119    let function_content = if let Some(TokenTree::Group(t)) = input.next() {
120        if t.delimiter() == Delimiter::Brace {
121            t.stream().to_string()
122        } else {
123            panic!("Expected function content")
124        }
125    } else {
126        panic!("Expected function content")
127    };
128    let func = &format!(
129        "fn main({}) -> Result<(), Box<dyn std::error::Error>> {{
130        let complete = std::sync::Arc::new(core::sync::atomic::AtomicBool::new(false));
131        let ender = complete.clone();
132        std::thread::spawn(||{{
133            executor::block_on(async move {{
134                (async {{
135                    {}
136                }}).await;
137                ender.store(true, core::sync::atomic::Ordering::Release);
138            }});
139        }});
140        while !complete.load(core::sync::atomic::Ordering::Acquire) {{}}
141        Ok(())
142    }}",
143        func_params, function_content
144    );
145    TokenStream::from_str(func).unwrap()
146}