1use proc_macro2::{Span, TokenStream};
4use quote::{format_ident, quote};
5
6pub(crate) fn argument_ident(name: &syn::Ident) -> syn::Ident {
7 match ::quote::__private::IdentFragmentAdapter(&crate::naming::unraw(name)) {
arg =>
::quote::__private::mk_ident(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("__mx_type_{0}", arg))
}),
::quote::__private::Option::Some::<::quote::__private::Span>(Span::mixed_site())),
}format_ident!(
8 "__mx_type_{}",
9 crate::naming::unraw(name),
10 span = Span::mixed_site()
11 )
12}
13
14pub(crate) fn setup(
17 inputs: &syn::punctuated::Punctuated<syn::FnArg, ::syn::token::Commasyn::Token![,]>,
18 receiver: bool,
19 callable: &TokenStream,
20) -> TokenStream {
21 let names: Vec<_> = inputs
22 .iter()
23 .filter_map(|arg| match arg {
24 syn::FnArg::Typed(arg) => match arg.pat.as_ref() {
25 syn::Pat::Ident(name) => Some(argument_ident(&name.ident)),
26 _ => None,
27 },
28 syn::FnArg::Receiver(_) => None,
29 })
30 .collect();
31 if names.is_empty() {
32 return TokenStream::new();
33 }
34 let args: Vec<_> = (0..names.len() + usize::from(receiver))
35 .map(|i| ::quote::__private::mk_ident(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("__MxArg{0}", i))
}),
::quote::__private::Option::Some::<::quote::__private::Span>(Span::mixed_site()))format_ident!("__MxArg{i}", span = Span::mixed_site()))
36 .collect();
37 let output = syn::Ident::new("__MxOutput", Span::mixed_site());
38 let helper = syn::Ident::new("__mx_argument_types", Span::mixed_site());
39 let receiver_slot = receiver.then(|| {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_underscore(&mut _s);
::quote::__private::push_comma(&mut _s);
_s
}quote!(_,));
40 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "let");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&receiver_slot, &mut _s);
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut names, i) = names.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let names =
match names.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&names, &mut _s);
::quote::__private::push_comma(&mut _s);
}
}
_s
});
::quote::__private::push_eq(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "fn");
::quote::ToTokens::to_tokens(&helper, &mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&output, &mut _s);
::quote::__private::push_comma(&mut _s);
{
use ::quote::__private::ext::*;
let mut _first = true;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut args, i) = args.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let args =
match args.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
if !_first { ::quote::__private::push_comma(&mut _s); }
_first = false;
::quote::ToTokens::to_tokens(&args, &mut _s);
}
}
::quote::__private::push_gt(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_underscore(&mut _s);
::quote::__private::push_colon(&mut _s);
::quote::__private::push_ident(&mut _s, "impl");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "core");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "ops");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "FnOnce");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let mut _first = true;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut args, i) = args.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let args =
match args.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
if !_first { ::quote::__private::push_comma(&mut _s); }
_first = false;
::quote::ToTokens::to_tokens(&args, &mut _s);
}
}
_s
});
::quote::__private::push_rarrow(&mut _s);
::quote::ToTokens::to_tokens(&output, &mut _s);
::quote::__private::push_comma(&mut _s);
_s
});
::quote::__private::push_rarrow(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut args, i) = args.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let args =
match args.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "trait_abi");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "signature");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Argument");
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&args, &mut _s);
::quote::__private::push_gt(&mut _s);
::quote::__private::push_comma(&mut _s);
}
}
_s
});
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut args, i) = args.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let args =
match args.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "miniextendr_api");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "trait_abi");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "signature");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "Argument");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_lt(&mut _s);
::quote::ToTokens::to_tokens(&args, &mut _s);
::quote::__private::push_gt(&mut _s);
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "NEW");
::quote::__private::push_comma(&mut _s);
}
}
_s
});
_s
});
::quote::ToTokens::to_tokens(&helper, &mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&callable, &mut _s);
_s
});
_s
});
::quote::__private::push_semi(&mut _s);
_s
}quote! {
41 let (#receiver_slot #(#names,)*) = {
42 fn #helper<#output, #(#args),*>(
43 _: impl ::core::ops::FnOnce(#(#args),*) -> #output,
44 ) -> (#(::miniextendr_api::trait_abi::signature::Argument<#args>,)*) {
45 (#(::miniextendr_api::trait_abi::signature::Argument::<#args>::NEW,)*)
46 }
47 #helper(#callable)
48 };
49 }
50}
51
52pub(crate) fn callable(sig: &syn::Signature, item: TokenStream) -> TokenStream {
55 if sig.unsafety.is_none() && sig.abi.is_none() {
56 return item;
57 }
58 let args: Vec<_> = (0..sig.inputs.len())
59 .map(|i| ::quote::__private::mk_ident(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("__mx_value{0}", i))
}),
::quote::__private::Option::Some::<::quote::__private::Span>(Span::mixed_site()))format_ident!("__mx_value{i}", span = Span::mixed_site()))
60 .collect();
61 let call = {
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&item, &mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let mut _first = true;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut args, i) = args.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let args =
match args.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
if !_first { ::quote::__private::push_comma(&mut _s); }
_first = false;
::quote::ToTokens::to_tokens(&args, &mut _s);
}
}
_s
});
_s
}quote! { #item(#(#args),*) };
62 let call = if sig.unsafety.is_some() {
63 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "unsafe");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Brace,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&call, &mut _s);
_s
});
_s
}quote! { unsafe { #call } }
64 } else {
65 call
66 };
67 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_or(&mut _s);
{
use ::quote::__private::ext::*;
let mut _first = true;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut args, i) = args.quote_into_iter();
let has_iter = has_iter | i;
<_ as ::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let args =
match args.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
if !_first { ::quote::__private::push_comma(&mut _s); }
_first = false;
::quote::ToTokens::to_tokens(&args, &mut _s);
}
}
::quote::__private::push_or(&mut _s);
::quote::ToTokens::to_tokens(&call, &mut _s);
_s
}quote! { |#(#args),*| #call }
68}