use proc_macro::TokenStream;
use proc_macro2::{Ident, Span};
use quote::quote;
use syn::{ExprCall, ExprPath, Path, PathSegment};
#[proc_macro]
pub fn bind(input: TokenStream) -> TokenStream {
let input: proc_macro2::TokenStream = input.into();
let mut call: ExprCall = syn::parse2(input).unwrap();
let placeholders = call
.args
.pairs_mut()
.filter_map(|pair| {
let value = pair.into_value();
matches!(value, syn::Expr::Infer(_)).then_some(value)
})
.enumerate()
.map(|(i, underscore)| {
let ident = format!("__{}", i);
let ident = Ident::new(&ident, Span::call_site());
let segment = PathSegment::from(ident);
let path = Path::from(segment);
let expr_path = ExprPath {
attrs: Vec::new(),
qself: None,
path,
};
*underscore = expr_path.clone().into();
expr_path
})
.collect::<Vec<_>>();
quote! {
|#(#placeholders),*| { #call }
}
.into()
}