@@ -42,6 +42,31 @@ pub fn jsg_struct(attr: TokenStream, item: TokenStream) -> TokenStream {
4242 } )
4343 } ) ;
4444
45+ let field_extractions = fields. named . iter ( ) . filter_map ( |field| {
46+ if !matches ! ( field. vis, syn:: Visibility :: Public ( _) ) {
47+ return None ;
48+ }
49+ let field_name = field. ident . as_ref ( ) ?;
50+ let field_name_str = field_name. to_string ( ) ;
51+ let field_type = & field. ty ;
52+ Some ( quote ! {
53+ let #field_name = {
54+ let prop = obj. get( lock, #field_name_str)
55+ . ok_or_else( || jsg:: Error :: new_type_error(
56+ format!( "Missing property '{}'" , #field_name_str)
57+ ) ) ?;
58+ <#field_type as jsg:: FromJS >:: from_js( lock, prop) ?
59+ } ;
60+ } )
61+ } ) ;
62+
63+ let field_names = fields. named . iter ( ) . filter_map ( |field| {
64+ if !matches ! ( field. vis, syn:: Visibility :: Public ( _) ) {
65+ return None ;
66+ }
67+ field. ident . as_ref ( )
68+ } ) ;
69+
4570 quote ! {
4671 #input
4772
@@ -73,8 +98,15 @@ pub fn jsg_struct(attr: TokenStream, item: TokenStream) -> TokenStream {
7398 impl jsg:: FromJS for #name {
7499 type ResultType = Self ;
75100
76- fn from_js( _lock: & mut jsg:: Lock , _value: jsg:: v8:: Local <jsg:: v8:: Value >) -> Result <Self :: ResultType , jsg:: Error > {
77- todo!( "Struct from_js is not yet supported" )
101+ fn from_js( lock: & mut jsg:: Lock , value: jsg:: v8:: Local <jsg:: v8:: Value >) -> Result <Self :: ResultType , jsg:: Error > {
102+ if !value. is_object( ) {
103+ return Err ( jsg:: Error :: new_type_error(
104+ format!( "Expected object but got {}" , value. type_of( ) )
105+ ) ) ;
106+ }
107+ let obj: jsg:: v8:: Local <' _, jsg:: v8:: Object > = value. into( ) ;
108+ #( #field_extractions) *
109+ Ok ( Self { #( #field_names) , * } )
78110 }
79111 }
80112
0 commit comments