Skip to content

Commit 35b2d20

Browse files
committed
add array support to rust/jsg
1 parent 27e8141 commit 35b2d20

File tree

8 files changed

+1503
-5
lines changed

8 files changed

+1503
-5
lines changed

src/rust/jsg-macros/lib.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)