Skip to content

Commit

Permalink
Add support for boa(rename = "") in TryFromJs derive (#3980)
Browse files Browse the repository at this point in the history
* Add support for boa(rename = "") in TryFromJs derive

* Fix clippies and fmt

* Move macro test to boa_engine
  • Loading branch information
hansl authored Sep 5, 2024
1 parent eecba59 commit 0f282f5
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 4 deletions.
36 changes: 36 additions & 0 deletions core/engine/tests/macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#![allow(unused_crate_dependencies)]
use boa_engine::value::TryFromJs;
use boa_engine::{js_string, Context, JsResult, JsValue, Source};
use boa_string::JsString;

#[test]
fn try_from_js_derive() {
#[derive(Debug, TryFromJs, Eq, PartialEq)]
struct TryFromJsTest {
a: JsString,
#[boa(rename = "bBB")]
b: i32,
#[boa(from_js_with = "check_tfj_called")]
c: i32,
}

fn check_tfj_called(value: &JsValue, context: &mut Context) -> JsResult<i32> {
let v = value.to_i32(context)?;
Ok(v / 2)
}

let mut context = Context::default();
let obj = context
.eval(Source::from_bytes(br#"({ a: "hello", bBB: 42, c: 120 })"#))
.unwrap();

let result = TryFromJsTest::try_from_js(&obj, &mut context).unwrap();
assert_eq!(
result,
TryFromJsTest {
a: js_string!("hello"),
b: 42,
c: 60
}
);
}
11 changes: 7 additions & 4 deletions core/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,12 +433,10 @@ fn generate_conversion(fields: FieldsNamed) -> Result<proc_macro2::TokenStream,
)]
})?;

let name_str = format!("{name}");
field_list.push(name.clone());

let error_str = format!("cannot get property {name_str} of value");

let mut from_js_with = None;
let mut field_name = format!("{name}");
if let Some(attr) = field
.attrs
.into_iter()
Expand All @@ -449,6 +447,10 @@ fn generate_conversion(fields: FieldsNamed) -> Result<proc_macro2::TokenStream,
let value = meta.value()?;
from_js_with = Some(value.parse::<LitStr>()?);
Ok(())
} else if meta.path.is_ident("rename") {
let value = meta.value()?;
field_name = value.parse::<LitStr>()?.value();
Ok(())
} else {
Err(meta.error(
"invalid syntax in the `#[boa()]` attribute. \
Expand All @@ -460,8 +462,9 @@ fn generate_conversion(fields: FieldsNamed) -> Result<proc_macro2::TokenStream,
.map_err(|err| vec![err])?;
}

let error_str = format!("cannot get property {name} of value");
final_fields.push(quote! {
let #name = match props.get(&::boa_engine::js_string!(#name_str).into()) {
let #name = match props.get(&::boa_engine::js_string!(#field_name).into()) {
Some(pd) => pd.value().ok_or_else(|| ::boa_engine::JsError::from(
::boa_engine::JsNativeError::typ().with_message(#error_str)
))?.clone().try_js_into(context)?,
Expand Down

0 comments on commit 0f282f5

Please sign in to comment.