1- mod types;
2-
31use proc_macro:: TokenStream ;
4- use proc_macro2:: TokenStream as TokenStream2 ;
52use quote:: ToTokens ;
63use quote:: quote;
74use syn:: Data ;
@@ -10,10 +7,8 @@ use syn::Fields;
107use syn:: FnArg ;
118use syn:: ItemFn ;
129use syn:: ItemImpl ;
13- use syn:: Type ;
1410use syn:: parse_macro_input;
1511use syn:: spanned:: Spanned ;
16- use types:: is_str_ref;
1712
1813/// Generates `jsg::Struct` and `jsg::Type` implementations for data structures.
1914///
@@ -51,27 +46,31 @@ pub fn jsg_struct(attr: TokenStream, item: TokenStream) -> TokenStream {
5146 #input
5247
5348 impl jsg:: Type for #name {
54- type This = Self ;
55-
5649 fn class_name( ) -> & ' static str { #class_name }
5750
58- fn wrap<' a, ' b>( this: Self :: This , lock: & ' a mut jsg:: Lock ) -> jsg:: v8:: Local <' b, jsg:: v8:: Value >
59- where ' b: ' a,
51+ fn is_exact( value: & jsg:: v8:: Local <jsg:: v8:: Value >) -> bool {
52+ value. is_object( )
53+ }
54+ }
55+
56+ impl jsg:: Wrappable for #name {
57+ fn wrap<' a, ' b>( self , lock: & ' a mut jsg:: Lock ) -> jsg:: v8:: Local <' b, jsg:: v8:: Value >
58+ where
59+ ' b: ' a,
6060 {
6161 // TODO(soon): Use a precached ObjectTemplate instance to create the object,
6262 // similar to how C++ JSG optimizes object creation. This would avoid recreating
6363 // the object shape on every wrap() call and improve performance.
6464 unsafe {
65+ let this = self ;
6566 let mut obj = lock. new_object( ) ;
6667 #( #field_assignments) *
6768 obj. into( )
6869 }
6970 }
71+ }
7072
71- fn is_exact( value: & jsg:: v8:: Local <jsg:: v8:: Value >) -> bool {
72- value. is_object( )
73- }
74-
73+ impl jsg:: Unwrappable for #name {
7574 fn unwrap( _isolate: jsg:: v8:: IsolatePtr , _value: jsg:: v8:: Local <jsg:: v8:: Value >) -> Self {
7675 unimplemented!( "Struct unwrap is not yet supported" )
7776 }
@@ -104,13 +103,15 @@ pub fn jsg_method(_attr: TokenStream, item: TokenStream) -> TokenStream {
104103 } )
105104 . collect ( ) ;
106105
107- let ( unwraps, arg_refs ) : ( Vec < _ > , Vec < _ > ) = params
106+ let ( unwraps, arg_names ) : ( Vec < _ > , Vec < _ > ) = params
108107 . iter ( )
109108 . enumerate ( )
110109 . map ( |( i, ty) | {
111110 let arg = syn:: Ident :: new ( & format ! ( "arg{i}" ) , fn_name. span ( ) ) ;
112- let ( unwrap, arg_ref) = generate_unwrap ( & arg, ty, i) ;
113- ( unwrap, arg_ref)
111+ let unwrap = quote ! {
112+ let Some ( #arg) = <#ty as jsg:: Unwrappable >:: try_unwrap( & mut lock, args. get( #i) ) else { return ; } ;
113+ } ;
114+ ( unwrap, arg)
114115 } )
115116 . unzip ( ) ;
116117
@@ -124,29 +125,13 @@ pub fn jsg_method(_attr: TokenStream, item: TokenStream) -> TokenStream {
124125 #( #unwraps) *
125126 let this = args. this( ) ;
126127 let self_ = jsg:: unwrap_resource:: <Self >( & mut lock, this) ;
127- let result = self_. #fn_name( #( #arg_refs ) , * ) ;
128- jsg:: Wrappable :: wrap_return ( result, & mut lock, & mut args ) ;
128+ let result = self_. #fn_name( #( #arg_names ) , * ) ;
129+ args . set_return_value ( jsg:: Wrappable :: wrap ( result, & mut lock) ) ;
129130 }
130131 }
131132 . into ( )
132133}
133134
134- fn generate_unwrap ( arg : & syn:: Ident , ty : & Type , index : usize ) -> ( TokenStream2 , TokenStream2 ) {
135- // &str: unwrap as String and borrow
136- if is_str_ref ( ty) {
137- let unwrap = quote ! {
138- let Some ( #arg) = <String as jsg:: Wrappable >:: try_unwrap( & mut lock, args. get( #index) ) else { return ; } ;
139- } ;
140- return ( unwrap, quote ! { & #arg } ) ;
141- }
142-
143- // All types use Wrappable::try_unwrap
144- let unwrap = quote ! {
145- let Some ( #arg) = <#ty as jsg:: Wrappable >:: try_unwrap( & mut lock, args. get( #index) ) else { return ; } ;
146- } ;
147- ( unwrap, quote ! { #arg } )
148- }
149-
150135/// Generates boilerplate for JSG resources.
151136///
152137/// On structs: generates `jsg::Type` and `ResourceTemplate`.
@@ -174,20 +159,25 @@ pub fn jsg_resource(attr: TokenStream, item: TokenStream) -> TokenStream {
174159
175160 #[ automatically_derived]
176161 impl jsg:: Type for #name {
177- type This = jsg:: Ref <Self >;
178-
179162 fn class_name( ) -> & ' static str { #class_name }
180163
181- fn wrap<' a, ' b>( _this: Self :: This , _lock: & ' a mut jsg:: Lock ) -> jsg:: v8:: Local <' b, jsg:: v8:: Value >
182- where ' b: ' a,
183- {
184- todo!( "Implement wrap for jsg::Resource" )
185- }
186-
187164 fn is_exact( value: & jsg:: v8:: Local <jsg:: v8:: Value >) -> bool {
188165 value. is_object( )
189166 }
167+ }
190168
169+ #[ automatically_derived]
170+ impl jsg:: Wrappable for #name {
171+ fn wrap<' a, ' b>( self , _lock: & ' a mut jsg:: Lock ) -> jsg:: v8:: Local <' b, jsg:: v8:: Value >
172+ where
173+ ' b: ' a,
174+ {
175+ unimplemented!( "Resource wrap is not yet supported" )
176+ }
177+ }
178+
179+ #[ automatically_derived]
180+ impl jsg:: Unwrappable for #name {
191181 fn unwrap( _isolate: jsg:: v8:: IsolatePtr , _value: jsg:: v8:: Local <jsg:: v8:: Value >) -> Self {
192182 unimplemented!( "Resource unwrap is not yet supported" )
193183 }
0 commit comments