miniextendr_macros/
trait_receiver.rs1use proc_macro2::TokenStream;
4use quote::quote;
5
6#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for OwnerReceiver { }
#[automatically_derived]
impl ::core::clone::Clone for OwnerReceiver {
#[inline]
fn clone(&self) -> Self { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for OwnerReceiver { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for OwnerReceiver {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
OwnerReceiver::Shared => "Shared",
OwnerReceiver::Mutable => "Mutable",
})
}
}Debug, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for OwnerReceiver { }
#[automatically_derived]
impl ::core::cmp::PartialEq for OwnerReceiver {
#[inline]
fn eq(&self, other: &Self) -> bool {
::core::intrinsics::discriminant_value(self) ==
::core::intrinsics::discriminant_value(other)
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for OwnerReceiver { }Eq)]
7pub(crate) enum OwnerReceiver {
8 Shared,
9 Mutable,
10}
11
12impl OwnerReceiver {
13 pub(crate) fn type_path(self) -> TokenStream {
14 match self {
15 Self::Shared => {
let mut _s = ::quote::__private::TokenStream::new();
::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, "ExternalPtrRef");
_s
}quote!(::miniextendr_api::ExternalPtrRef),
16 Self::Mutable => {
let mut _s = ::quote::__private::TokenStream::new();
::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, "ExternalPtrMut");
_s
}quote!(::miniextendr_api::ExternalPtrMut),
17 }
18 }
19}
20
21pub(crate) fn owner_receiver(sig: &syn::Signature) -> Option<OwnerReceiver> {
22 let receiver = sig.receiver()?;
23 receiver.colon_token?;
25 let syn::Type::Path(path) = receiver.ty.as_ref() else {
26 return None;
27 };
28 if path.qself.is_some() {
29 return None;
30 }
31 let segment = path.path.segments.last()?;
32 let kind = match segment.ident.to_string().as_str() {
33 "ExternalPtrRef" => OwnerReceiver::Shared,
34 "ExternalPtrMut" => OwnerReceiver::Mutable,
35 _ => return None,
36 };
37 let syn::PathArguments::AngleBracketed(args) = &segment.arguments else {
38 return None;
39 };
40 let mut types = args.args.iter().filter_map(|arg| match arg {
41 syn::GenericArgument::Type(ty) => Some(ty),
42 _ => None,
43 });
44 match (types.next(), types.next()) {
45 (Some(syn::Type::Path(ty)), None) if ty.qself.is_none() && ty.path.is_ident("Self") => {
46 Some(kind)
47 }
48 _ => None,
49 }
50}
51
52pub(crate) fn is_mut(sig: &syn::Signature) -> bool {
53 match owner_receiver(sig) {
54 Some(OwnerReceiver::Mutable) => true,
55 Some(OwnerReceiver::Shared) => false,
56 None => sig
57 .receiver()
58 .is_some_and(|receiver| match receiver.ty.as_ref() {
59 syn::Type::Reference(reference) => reference.mutability.is_some(),
60 _ => receiver.mutability.is_some(),
61 }),
62 }
63}
64
65pub(crate) fn rewrite(sig: &mut syn::Signature, body: Option<&mut syn::Block>) {
68 if owner_receiver(sig).is_none() {
69 return;
70 }
71 let receiver = sig.receiver().expect("owner receiver");
72 let ty = receiver.ty.clone();
73 let mutability = receiver.mutability;
74 let receiver_ident = syn::Ident::new("__miniextendr_self", proc_macro2::Span::mixed_site());
75 sig.inputs[0] = ::syn::__private::parse_quote({
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&receiver_ident, &mut _s);
::quote::__private::push_colon(&mut _s);
::quote::ToTokens::to_tokens(&ty, &mut _s);
_s
})syn::parse_quote!(#receiver_ident: #ty);
76 if let Some(body) = body {
77 sig.inputs[0] = ::syn::__private::parse_quote({
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&mutability, &mut _s);
::quote::ToTokens::to_tokens(&receiver_ident, &mut _s);
::quote::__private::push_colon(&mut _s);
::quote::ToTokens::to_tokens(&ty, &mut _s);
_s
})syn::parse_quote!(#mutability #receiver_ident: #ty);
78 crate::receiver_body::rewrite(body, &receiver_ident);
79 }
80}