|
|
@ -124,22 +124,33 @@ impl JsValue { |
|
|
|
.with_message("cannot convert bigint to JSON") |
|
|
|
.with_message("cannot convert bigint to JSON") |
|
|
|
.into()), |
|
|
|
.into()), |
|
|
|
Self::Object(obj) => { |
|
|
|
Self::Object(obj) => { |
|
|
|
|
|
|
|
let value_by_prop_key = |property_key, context: &mut Context| { |
|
|
|
|
|
|
|
obj.borrow() |
|
|
|
|
|
|
|
.properties() |
|
|
|
|
|
|
|
.get(&property_key) |
|
|
|
|
|
|
|
.and_then(|x| x.value().map(|val| val.to_json(context))) |
|
|
|
|
|
|
|
.unwrap_or(Ok(Value::Null)) |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
if obj.is_array() { |
|
|
|
if obj.is_array() { |
|
|
|
let len = obj.length_of_array_like(context)?; |
|
|
|
let len = obj.length_of_array_like(context)?; |
|
|
|
let mut arr = Vec::with_capacity(len as usize); |
|
|
|
let mut arr = Vec::with_capacity(len as usize); |
|
|
|
|
|
|
|
|
|
|
|
let obj = obj.borrow(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for k in 0..len as u32 { |
|
|
|
for k in 0..len as u32 { |
|
|
|
let val = obj.properties().get(&k.into()).map_or(Self::Null, |desc| { |
|
|
|
let val = value_by_prop_key(k.into(), context)?; |
|
|
|
desc.value().cloned().unwrap_or(Self::Null) |
|
|
|
arr.push(val); |
|
|
|
}); |
|
|
|
|
|
|
|
arr.push(val.to_json(context)?); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Ok(Value::Array(arr)) |
|
|
|
Ok(Value::Array(arr)) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
let mut map = Map::new(); |
|
|
|
let mut map = Map::new(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for index in obj.borrow().properties().index_property_keys() { |
|
|
|
|
|
|
|
let key = index.to_string(); |
|
|
|
|
|
|
|
let value = value_by_prop_key(index.into(), context)?; |
|
|
|
|
|
|
|
map.insert(key, value); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for property_key in obj.borrow().properties().shape.keys() { |
|
|
|
for property_key in obj.borrow().properties().shape.keys() { |
|
|
|
let key = match &property_key { |
|
|
|
let key = match &property_key { |
|
|
|
PropertyKey::String(string) => string.to_std_string_escaped(), |
|
|
|
PropertyKey::String(string) => string.to_std_string_escaped(), |
|
|
@ -150,17 +161,7 @@ impl JsValue { |
|
|
|
.into()) |
|
|
|
.into()) |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
let value = value_by_prop_key(property_key, context)?; |
|
|
|
let value = match obj |
|
|
|
|
|
|
|
.borrow() |
|
|
|
|
|
|
|
.properties() |
|
|
|
|
|
|
|
.get(&property_key) |
|
|
|
|
|
|
|
.and_then(|x| x.value().cloned()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Some(val) => val.to_json(context)?, |
|
|
|
|
|
|
|
None => Value::Null, |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
map.insert(key, value); |
|
|
|
map.insert(key, value); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -181,7 +182,7 @@ mod tests { |
|
|
|
use serde_json::json; |
|
|
|
use serde_json::json; |
|
|
|
|
|
|
|
|
|
|
|
use crate::object::JsArray; |
|
|
|
use crate::object::JsArray; |
|
|
|
use crate::JsValue; |
|
|
|
use crate::{js_string, JsValue}; |
|
|
|
use crate::{run_test_actions, TestAction}; |
|
|
|
use crate::{run_test_actions, TestAction}; |
|
|
|
|
|
|
|
|
|
|
|
#[test] |
|
|
|
#[test] |
|
|
@ -200,7 +201,10 @@ mod tests { |
|
|
|
-45, |
|
|
|
-45, |
|
|
|
{}, |
|
|
|
{}, |
|
|
|
true |
|
|
|
true |
|
|
|
] |
|
|
|
], |
|
|
|
|
|
|
|
"7.3": "random text", |
|
|
|
|
|
|
|
"100": 1000, |
|
|
|
|
|
|
|
"24": 42 |
|
|
|
} |
|
|
|
} |
|
|
|
"#}; |
|
|
|
"#}; |
|
|
|
|
|
|
|
|
|
|
@ -217,6 +221,14 @@ mod tests { |
|
|
|
assert_eq!(obj.get(js_str!("age"), ctx).unwrap(), 43_i32.into()); |
|
|
|
assert_eq!(obj.get(js_str!("age"), ctx).unwrap(), 43_i32.into()); |
|
|
|
assert_eq!(obj.get(js_str!("minor"), ctx).unwrap(), false.into()); |
|
|
|
assert_eq!(obj.get(js_str!("minor"), ctx).unwrap(), false.into()); |
|
|
|
assert_eq!(obj.get(js_str!("adult"), ctx).unwrap(), true.into()); |
|
|
|
assert_eq!(obj.get(js_str!("adult"), ctx).unwrap(), true.into()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert_eq!( |
|
|
|
|
|
|
|
obj.get(js_str!("7.3"), ctx).unwrap(), |
|
|
|
|
|
|
|
js_string!("random text").into() |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
assert_eq!(obj.get(js_str!("100"), ctx).unwrap(), 1000.into()); |
|
|
|
|
|
|
|
assert_eq!(obj.get(js_str!("24"), ctx).unwrap(), 42.into()); |
|
|
|
|
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
let extra = obj.get(js_str!("extra"), ctx).unwrap(); |
|
|
|
let extra = obj.get(js_str!("extra"), ctx).unwrap(); |
|
|
|
let extra = extra.as_object().unwrap(); |
|
|
|
let extra = extra.as_object().unwrap(); |
|
|
|