1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, LitInt};
4
5#[proc_macro_attribute]
7pub fn concurrency_limit(attr: TokenStream, item: TokenStream) -> TokenStream {
8 let limit = parse_macro_input!(attr as LitInt);
9 let input = parse_macro_input!(item as syn::ItemFn);
10
11 let fn_name = &input.sig.ident;
12 let semaphore_name = quote::format_ident!("SEMAPHORE_{}", fn_name);
13
14 quote! {
15 static #semaphore_name: ::once_cell::sync::Lazy<::tokio::sync::Semaphore> =
16 ::once_cell::sync::Lazy::new(|| ::tokio::sync::Semaphore::new(#limit));
17
18 #input
19
20 impl #fn_name {
21 pub async fn acquire() -> ::tokio::sync::SemaphorePermit<'static> {
22 #semaphore_name.acquire().await.unwrap()
23 }
24 }
25 }.into()
26}