use proc_macro::TokenStream;
use quote::quote;
use syn::{parse_macro_input, LitInt};
#[proc_macro_attribute]
pub fn concurrency_limit(attr: TokenStream, item: TokenStream) -> TokenStream {
let limit = parse_macro_input!(attr as LitInt);
let input = parse_macro_input!(item as syn::ItemFn);
let fn_name = &input.sig.ident;
let semaphore_name = quote::format_ident!("SEMAPHORE_{}", fn_name);
quote! {
static #semaphore_name: ::once_cell::sync::Lazy<::tokio::sync::Semaphore> =
::once_cell::sync::Lazy::new(|| ::tokio::sync::Semaphore::new(#limit));
#input
impl #fn_name {
pub async fn acquire() -> ::tokio::sync::SemaphorePermit<'static> {
#semaphore_name.acquire().await.unwrap()
}
}
}.into()
}