Browse Source

Add support for boa(rename = "") in TryFromJs derive (#3980)

* Add support for boa(rename = "") in TryFromJs derive

* Fix clippies and fmt

* Move macro test to boa_engine
pull/3985/head
Hans Larsen 4 months ago committed by GitHub
parent
commit
0f282f5bc3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 36
      core/engine/tests/macros.rs
  2. 11
      core/macros/src/lib.rs

36
core/engine/tests/macros.rs

@ -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
core/macros/src/lib.rs

@ -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()
@ -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. \
@ -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)?,

Loading…
Cancel
Save