From 78713a1b4ecd2ca79ce110194d76a0f71d287bd2 Mon Sep 17 00:00:00 2001 From: alemi Date: Sat, 12 Oct 2024 22:25:57 +0200 Subject: [PATCH] feat: handle more complex return types --- macro/src/args.rs | 23 ++--------------------- macro/src/ext.rs | 21 +++++++++++++++++++++ macro/src/lib.rs | 1 + macro/src/ret.rs | 8 +++++--- 4 files changed, 29 insertions(+), 24 deletions(-) create mode 100644 macro/src/ext.rs diff --git a/macro/src/args.rs b/macro/src/args.rs index 0719ec5..7bfe71e 100644 --- a/macro/src/args.rs +++ b/macro/src/args.rs @@ -2,6 +2,8 @@ use proc_macro2::{Span, TokenStream}; use quote::TokenStreamExt; use syn::Ident; +use crate::ext::bare_type; + pub(crate) struct ArgumentOptions { pub(crate) incoming: TokenStream, pub(crate) transforming: TokenStream, @@ -22,27 +24,6 @@ fn unpack_pat(pat: syn::Pat) -> Result { } } -fn bare_type(ty: Box) -> Option { - match *ty { - syn::Type::Array(a) => bare_type(a.elem), - syn::Type::BareFn(_) => None, - syn::Type::ImplTrait(_) => None, - syn::Type::Infer(_) => None, - syn::Type::Macro(_) => None, - syn::Type::Never(_) => None, - syn::Type::TraitObject(_) => None, - syn::Type::Verbatim(_) => None, - syn::Type::Ptr(p) => bare_type(p.elem), - syn::Type::Slice(s) => bare_type(s.elem), - syn::Type::Tuple(t) => bare_type(Box::new(t.elems.first()?.clone())), // TODO - syn::Type::Group(g) => bare_type(g.elem), - syn::Type::Paren(p) => bare_type(p.elem), - syn::Type::Reference(r) => bare_type(r.elem), - syn::Type::Path(ty) => Some(ty), - _ => todo!(), - } -} - fn type_equals(ty: Box, search: impl AsRef) -> bool { let Some(ty) = bare_type(ty) else { return false }; let Some(last) = ty.path.segments.last() else { return false }; diff --git a/macro/src/ext.rs b/macro/src/ext.rs new file mode 100644 index 0000000..e7763a0 --- /dev/null +++ b/macro/src/ext.rs @@ -0,0 +1,21 @@ + +pub(crate) fn bare_type(ty: Box) -> Option { + match *ty { + syn::Type::Array(a) => bare_type(a.elem), + syn::Type::BareFn(_) => None, + syn::Type::ImplTrait(_) => None, + syn::Type::Infer(_) => None, + syn::Type::Macro(_) => None, + syn::Type::Never(_) => None, + syn::Type::TraitObject(_) => None, + syn::Type::Verbatim(_) => None, + syn::Type::Ptr(p) => bare_type(p.elem), + syn::Type::Slice(s) => bare_type(s.elem), + syn::Type::Tuple(t) => bare_type(Box::new(t.elems.first()?.clone())), // TODO + syn::Type::Group(g) => bare_type(g.elem), + syn::Type::Paren(p) => bare_type(p.elem), + syn::Type::Reference(r) => bare_type(r.elem), + syn::Type::Path(ty) => Some(ty), + _ => todo!(), + } +} diff --git a/macro/src/lib.rs b/macro/src/lib.rs index 6f3e595..f4b824e 100644 --- a/macro/src/lib.rs +++ b/macro/src/lib.rs @@ -2,6 +2,7 @@ mod attrs; mod wrapper; mod args; mod ret; +mod ext; /// Wrap this function in in a JNI exported fn. #[proc_macro_attribute] diff --git a/macro/src/ret.rs b/macro/src/ret.rs index 5934e30..fec137a 100644 --- a/macro/src/ret.rs +++ b/macro/src/ret.rs @@ -2,6 +2,8 @@ use proc_macro2::{Span, TokenStream}; use quote::ToTokens; use syn::{ReturnType, Type}; +use crate::ext::bare_type; + #[derive(Clone)] pub(crate) struct ReturnOptions { pub(crate) ty: Option>, @@ -16,8 +18,8 @@ impl ReturnOptions { pub(crate) fn parse_signature(ret: &ReturnType) -> Result { match ret { syn::ReturnType::Default => Ok(Self { ty: None, result: false, void: true, pointer: false }), - syn::ReturnType::Type(_tok, ty) => match *ty.clone() { - syn::Type::Path(path) => { + syn::ReturnType::Type(_tok, ty) => match bare_type(ty.clone()) { + Some(path) => { let Some(last) = path.path.segments.last() else { return Err(syn::Error::new(Span::call_site(), "empty Result type is not valid")); }; @@ -43,7 +45,7 @@ impl ReturnOptions { let pointer = !PRIMITIVE_TYPES.iter().any(|t| last.ident == t); Ok(Self { ty: Some(Box::new(Type::Path(path.clone()))), result: false, void: false, pointer }) }, - _ => Err(syn::Error::new(Span::call_site(), "unsupported return type")), + None => Err(syn::Error::new(Span::call_site(), "unsupported return type")), }, } }