1#![allow(unused_doc_comments)]
12#![allow(dead_code)]
13
14#![allow(unused_imports)]
15#![allow(unused_variables)]
16#![allow(unused_assignments)]
17
18use proc_macro::TokenStream;
19use proc_macro2::Span;
20use quote::{quote, quote_spanned};
21use syn::parse::{Parse, ParseStream};
22use syn::spanned::Spanned;
23use syn::Expr;
24use futures::executor::block_on;
25
26#[proc_macro_attribute]
27pub fn main(attr: TokenStream, item: TokenStream) -> TokenStream {
28 let input = syn::parse_macro_input!(item as syn::ItemFn);
29 let opts = syn::parse_macro_input!(attr as Opts);
30
31 let ret = &input.sig.output;
32 let inputs = &input.sig.inputs;
33 let name = &input.sig.ident;
34 let body = &input.block;
35 #[allow(unused_variables)]
36 let attrs = &input.attrs;
37 let vis = &input.vis;
38
39 let crate_root = opts.crate_root;
40
41 let threads = match opts.threads {
42 Some((num, span)) => {
43 let num = num.to_string();
44 Some(quote_spanned!(span=> #num))
45 }
46 #[cfg(feature = "auto")]
47 None => Some(quote! {
48 #crate_root::std::string::ToString::to_string(
49 &#crate_root::std::cmp::max(#crate_root::num_cpus::get(), 1)
50 )
51 }),
52 #[cfg(not(feature = "auto"))]
53 None => None,
54 };
55
56 #[allow(unused_variables)]
57 let set_threads = threads.map(|threads| {
58 quote! {
59 #crate_root::std::env::set_var(
60 "RUSTBASIC-THREADS",
61 #threads,
62 );
63 }
64 });
65
66 let mut result : proc_macro2::TokenStream = proc_macro2::TokenStream::new();
67
68 match input.sig.asyncness {
69 None | Some(_) if input.sig.ident != "main" => { result = quote! {
71 #vis fn #name(#inputs) #ret {
72 #body
73 }
74 }
75 }
76 _ => { result = quote! {
78 #vis fn main() #ret {
79 futures::executor::block_on( async { async_main().await } );
80 }
81 async fn async_main() #ret {
82 #body
83 }
84 }
85 }
86 }
87
88 result.into()
89}
90
91#[proc_macro_attribute]
92pub fn print(attr: TokenStream, item: TokenStream) -> TokenStream {
93
94 println!("attr: {:?}", attr.clone());
95 println!("item: {:?}", item.clone());
96
97 let input = syn::parse_macro_input!(item as syn::ItemFn);
98 let opts = syn::parse_macro_input!(attr as Opts);
99
100let ret = &input.sig.output;
104 let inputs = &input.sig.inputs;
105 let name = &input.sig.ident;
106 let body = &input.block;
107 #[allow(unused_variables)]
108 let attrs = &input.attrs;
109 let vis = &input.vis;
110
111 let crate_root = opts.crate_root;
112
113 let threads = match opts.threads {
114 Some((num, span)) => {
115 let num = num.to_string();
116 Some(quote_spanned!(span=> #num))
117 }
118 #[cfg(feature = "auto")]
119 None => Some(quote! {
120 #crate_root::std::string::ToString::to_string(
121 &#crate_root::std::cmp::max(#crate_root::num_cpus::get(), 1)
122 )
123 }),
124 #[cfg(not(feature = "auto"))]
125 None => None,
126 };
127
128 #[allow(unused_variables)]
129 let set_threads = threads.map(|threads| {
130 quote! {
131 #crate_root::std::env::set_var(
132 "RUSTBASIC-THREADS",
133 #threads,
134 );
135 }
136 });
137
138 let result : proc_macro2::TokenStream = proc_macro2::TokenStream::new();
139result.into()
169}
170
171#[proc_macro_attribute]
172pub fn start(attr: TokenStream, item: TokenStream) -> TokenStream {
173 let input = syn::parse_macro_input!(item as syn::ItemFn);
174 let opts = syn::parse_macro_input!(attr as Opts);
175
176 let ret = &input.sig.output;
177 let inputs = &input.sig.inputs;
178 let name = &input.sig.ident;
179 let body = &input.block;
180 #[allow(unused_variables)]
181 let attrs = &input.attrs;
182 let vis = &input.vis;
183
184 let crate_root = opts.crate_root;
185
186 let threads = match opts.threads {
187 Some((num, span)) => {
188 let num = num.to_string();
189 Some(quote_spanned!(span=> #num))
190 }
191 #[cfg(feature = "auto")]
192 None => Some(quote! {
193 #crate_root::std::string::ToString::to_string(
194 &#crate_root::std::cmp::max(#crate_root::num_cpus::get(), 1)
195 )
196 }),
197 #[cfg(not(feature = "auto"))]
198 None => None,
199 };
200
201 #[allow(unused_variables)]
202 let set_threads = threads.map(|threads| {
203 quote! {
204 #crate_root::std::env::set_var(
205 "RUSTBASIC-THREADS",
206 #threads,
207 );
208 }
209 });
210
211 let mut result : proc_macro2::TokenStream = proc_macro2::TokenStream::new();
212
213 match input.sig.asyncness {
214 None | Some(_) if input.sig.ident != "main" => { result = quote! {
216 #[allow(unused_imports)]
217 #[allow(unused_attributes)]
218 #[allow(dead_code)]
219 #[allow(unused_variables)]
220 #[allow(unused_assignments)]
221 #[allow(unused_doc_comments)]
222 #vis fn #name(#inputs) #ret {
223 #body
224 }
225 }
226 }
227 _ => { result = quote! {
229 #vis fn main() #ret {
230 futures::executor::block_on( async { async_main().await } );
231 }
232 #[allow(unused_imports)]
233 #[allow(unused_attributes)]
234 #[allow(dead_code)]
235 #[allow(unused_variables)]
236 #[allow(unused_assignments)]
237 #[allow(unused_doc_comments)]
238 async fn async_main() #ret {
239 #body
240 }
241 }
242 }
243 }
244
245 result.into()
246}
247
248#[proc_macro_attribute]
249pub fn func(attr: TokenStream, item: TokenStream) -> TokenStream {
250 let input = syn::parse_macro_input!(item as syn::ItemFn);
251 let opts = syn::parse_macro_input!(attr as Opts);
252
253 let ret = &input.sig.output;
254 let inputs = &input.sig.inputs;
255 let name = &input.sig.ident;
256 let body = &input.block;
257 #[allow(unused_variables)]
258 let attrs = &input.attrs;
259 let vis = &input.vis;
260
261 let crate_root = opts.crate_root;
262
263 let threads = match opts.threads {
264 Some((num, span)) => {
265 let num = num.to_string();
266 Some(quote_spanned!(span=> #num))
267 }
268 #[cfg(feature = "auto")]
269 None => Some(quote! {
270 #crate_root::std::string::ToString::to_string(
271 &#crate_root::std::cmp::max(#crate_root::num_cpus::get(), 1)
272 )
273 }),
274 #[cfg(not(feature = "auto"))]
275 None => None,
276 };
277
278 #[allow(unused_variables)]
279 let set_threads = threads.map(|threads| {
280 quote! {
281 #crate_root::std::env::set_var(
282 "RUSTBASIC-THREADS",
283 #threads,
284 );
285 }
286 });
287
288 let mut result : proc_macro2::TokenStream = proc_macro2::TokenStream::new();
289
290 match input.sig.asyncness {
291 None => { result = quote! {
293 #[allow(unused_imports)]
294 #[allow(unused_attributes)]
295 #[allow(dead_code)]
296 #[allow(unused_variables)]
297 #[allow(unused_assignments)]
298 #[allow(unused_doc_comments)]
299 #vis fn #name(#inputs) #ret {
300 #body
301 }
302 }
303 },
304 Some(_) if input.sig.ident != "main" => { result = quote! {
306 #[allow(unused_imports)]
307 #[allow(unused_attributes)]
308 #[allow(dead_code)]
309 #[allow(unused_variables)]
310 #[allow(unused_assignments)]
311 #[allow(unused_doc_comments)]
312 #vis fn rustbasic_asyncfunc() #ret {
313 async fn #name(#inputs) {
314 #body
315 }
316 futures::executor::block_on( async {
317 #name().await;
318 } );
319 }
320 }
321 },
322 _ => { result = quote! {
324 #vis fn main() #ret {
325 futures::executor::block_on( async { async_main().await } );
326 }
327 #[allow(unused_imports)]
328 #[allow(unused_attributes)]
329 #[allow(dead_code)]
330 #[allow(unused_variables)]
331 #[allow(unused_doc_comments)]
332 async fn async_main() #ret {
333 #body
334 }
335 }
336 }
337 }
338
339 result.into()
340}
341
342#[proc_macro_attribute]
343pub fn function(attr: TokenStream, item: TokenStream) -> TokenStream {
344 let input = syn::parse_macro_input!(item as syn::ItemFn);
345 let opts = syn::parse_macro_input!(attr as Opts);
346
347 let ret = &input.sig.output;
348 let inputs = &input.sig.inputs;
349 let name = &input.sig.ident;
350 let body = &input.block;
351 #[allow(unused_variables)]
352 let attrs = &input.attrs;
353 let vis = &input.vis;
354
355 let crate_root = opts.crate_root;
356
357 let threads = match opts.threads {
358 Some((num, span)) => {
359 let num = num.to_string();
360 Some(quote_spanned!(span=> #num))
361 }
362 #[cfg(feature = "auto")]
363 None => Some(quote! {
364 #crate_root::std::string::ToString::to_string(
365 &#crate_root::std::cmp::max(#crate_root::num_cpus::get(), 1)
366 )
367 }),
368 #[cfg(not(feature = "auto"))]
369 None => None,
370 };
371
372 #[allow(unused_variables)]
373 let set_threads = threads.map(|threads| {
374 quote! {
375 #crate_root::std::env::set_var(
376 "RUSTBASIC-THREADS",
377 #threads,
378 );
379 }
380 });
381
382 let result : proc_macro2::TokenStream;
383
384 match input.sig.asyncness {
385 None | Some(_) if input.sig.ident != "main" => { result = quote! {
387 #[allow(unused_imports)]
388 #[allow(unused_attributes)]
389 #[allow(dead_code)]
390 #[allow(unused_variables)]
391 #[allow(unused_doc_comments)]
392 #vis fn #name(#inputs) #ret {
393 #body
394 }
395 }
396 }
397 _ => { result = quote! {
399 #vis fn main() #ret {
400 futures::executor::block_on( async { async_main().await } );
401 }
402 #[allow(unused_imports)]
403 #[allow(unused_attributes)]
404 #[allow(dead_code)]
405 #[allow(unused_variables)]
406 #[allow(unused_doc_comments)]
407 async fn async_main() #ret {
408 #body
409 }
410 }
411 }
412 }
413
414 result.into()
415}
416
417struct Opts {
418 crate_root: syn::Path,
419 threads: Option<(u32, Span)>,
420}
421
422impl Parse for Opts {
423 fn parse(input: ParseStream<'_>) -> syn::Result<Self> {
424 let mut crate_root = None;
425 let mut threads = None;
426
427 loop {
428 if input.is_empty() {
429 break;
430 }
431
432 let name_value: syn::MetaNameValue = input.parse()?;
433 let ident = match name_value.path.get_ident() {
434 Some(ident) => ident,
435 None => {
436 return Err(syn::Error::new_spanned(
437 name_value.path,
438 "Must be a single ident",
439 ))
440 }
441 };
442 match &*ident.to_string().to_lowercase() {
443 "threads" => match &name_value.lit {
444 syn::Lit::Int(expr) => {
445 if threads.is_some() {
446 return Err(syn::Error::new_spanned(
447 name_value,
448 "multiple threads argments",
449 ));
450 }
451
452 let num = expr.base10_parse::<std::num::NonZeroU32>()?;
453 threads = Some((num.get(), expr.span()));
454 }
455 _ => {
456 return Err(syn::Error::new_spanned(
457 name_value,
458 "threads argument must be an integer",
459 ))
460 }
461 },
462 "crate" => match &name_value.lit {
463 syn::Lit::Str(path) => {
464 if crate_root.is_some() {
465 return Err(syn::Error::new_spanned(
466 name_value,
467 "multiple crate arguments",
468 ));
469 }
470
471 crate_root = Some(path.parse()?);
472 }
473 _ => {
474 return Err(syn::Error::new_spanned(
475 name_value,
476 "crate argument must be a string",
477 ))
478 }
479 },
480 name => {
481 return Err(syn::Error::new_spanned(
482 name,
483 "unknown attribute {}, expected `threads` or `crate`",
484 ));
485 }
486 }
487
488 input.parse::<Option<syn::Token![,]>>()?;
489 }
490
491 Ok(Self {
492 crate_root: crate_root.unwrap_or_else(|| syn::parse2(quote!(::rustbasic)).unwrap()),
493 threads,
494 })
495 }
496}
497
498async fn rustbasic_macro_addlib_temp() {
499}
500
501fn rustbasic_macro_addlib() {
502 futures::executor::block_on( rustbasic_macro_addlib_temp() );
503}