@@ -2,6 +2,8 @@ use crate::export::function::meta::Kind;
2
2
3
3
pub ( crate ) mod meta;
4
4
5
+ static ASYNC_CX_ERROR : & str = "`FunctionContext` is not allowed in async functions" ;
6
+ static ASYNC_FN_ERROR : & str = "`async` attribute should not be used with an `async fn`" ;
5
7
static TASK_CX_ERROR : & str = "`FunctionContext` is not allowed with `task` attribute" ;
6
8
7
9
pub ( super ) fn export ( meta : meta:: Meta , input : syn:: ItemFn ) -> proc_macro:: TokenStream {
@@ -40,19 +42,19 @@ pub(super) fn export(meta: meta::Meta, input: syn::ItemFn) -> proc_macro::TokenS
40
42
. unwrap_or_else ( || quote:: quote!( #name) )
41
43
} ) ;
42
44
43
- // Import the value or JSON trait for conversion
44
- let result_trait_name = if meta. json {
45
- quote:: format_ident!( "NeonExportReturnJson " )
45
+ // Tag whether we should JSON wrap results
46
+ let return_tag = if meta. json {
47
+ quote:: format_ident!( "NeonJsonTag " )
46
48
} else {
47
- quote:: format_ident!( "NeonExportReturnValue " )
49
+ quote:: format_ident!( "NeonValueTag " )
48
50
} ;
49
51
50
52
// Convert the result
51
53
// N.B.: Braces are intentionally included to avoid leaking trait to function body
52
54
let result_extract = quote:: quote!( {
53
- use neon:: macro_internal:: #result_trait_name ;
55
+ use neon:: macro_internal:: { ToNeonMarker , #return_tag as NeonReturnTag } ;
54
56
55
- res. try_neon_export_return ( & mut cx)
57
+ ( & res) . to_neon_marker :: < NeonReturnTag > ( ) . neon_into_js ( & mut cx, res )
56
58
} ) ;
57
59
58
60
// Default export name as identity unless a name is provided
@@ -63,6 +65,17 @@ pub(super) fn export(meta: meta::Meta, input: syn::ItemFn) -> proc_macro::TokenS
63
65
64
66
// Generate the call to the original function
65
67
let call_body = match meta. kind {
68
+ Kind :: Async | Kind :: AsyncFn => quote:: quote!(
69
+ let ( #( #tuple_fields, ) * ) = cx. args( ) ?;
70
+ let fut = #name( #context_arg #( #args) , * ) ;
71
+ let fut = {
72
+ use neon:: macro_internal:: { ToNeonMarker , NeonValueTag } ;
73
+
74
+ ( & fut) . to_neon_marker:: <NeonValueTag >( ) . into_neon_result( & mut cx, fut) ?
75
+ } ;
76
+
77
+ neon:: macro_internal:: spawn( & mut cx, fut, |mut cx, res| #result_extract)
78
+ ) ,
66
79
Kind :: Normal => quote:: quote!(
67
80
let ( #( #tuple_fields, ) * ) = cx. args( ) ?;
68
81
let res = #name( #context_arg #( #args) , * ) ;
@@ -160,7 +173,8 @@ fn has_context_arg(meta: &meta::Meta, sig: &syn::Signature) -> syn::Result<bool>
160
173
161
174
// Context is only allowed for normal functions
162
175
match meta. kind {
163
- Kind :: Normal => { }
176
+ Kind :: Normal | Kind :: Async => { }
177
+ Kind :: AsyncFn => return Err ( syn:: Error :: new ( first. span ( ) , ASYNC_CX_ERROR ) ) ,
164
178
Kind :: Task => return Err ( syn:: Error :: new ( first. span ( ) , TASK_CX_ERROR ) ) ,
165
179
}
166
180
0 commit comments