From b0800c41b9b1722614e10c946f0ad9c5bca8c55e Mon Sep 17 00:00:00 2001 From: Nikita-str Date: Sat, 28 Sep 2024 17:21:41 +0300 Subject: [PATCH 1/2] #3923: `to_json` fix integer properties key --- .../src/value/conversions/serde_json.rs | 44 ++++++++++++++----- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/core/engine/src/value/conversions/serde_json.rs b/core/engine/src/value/conversions/serde_json.rs index 104d928e7c9..09dbf5e3ced 100644 --- a/core/engine/src/value/conversions/serde_json.rs +++ b/core/engine/src/value/conversions/serde_json.rs @@ -140,6 +140,25 @@ impl JsValue { Ok(Value::Array(arr)) } else { let mut map = Map::new(); + let mut value_by_prop_key = |property_key| match obj + .borrow() + .properties() + .get(&property_key) + .and_then(|x| x.value().cloned()) + { + Some(val) => val.to_json(context), + None => Ok(Value::Null), + }; + + for index in obj.borrow().properties().index_property_keys() { + let key = index.to_string(); + + let property_key = PropertyKey::from(index); + let value = value_by_prop_key(property_key)?; + + map.insert(key, value); + } + for property_key in obj.borrow().properties().shape.keys() { let key = match &property_key { PropertyKey::String(string) => string.to_std_string_escaped(), @@ -151,15 +170,7 @@ impl JsValue { } }; - let value = match obj - .borrow() - .properties() - .get(&property_key) - .and_then(|x| x.value().cloned()) - { - Some(val) => val.to_json(context)?, - None => Value::Null, - }; + let value = value_by_prop_key(property_key)?; map.insert(key, value); } @@ -181,7 +192,7 @@ mod tests { use serde_json::json; use crate::object::JsArray; - use crate::JsValue; + use crate::{js_string, JsValue}; use crate::{run_test_actions, TestAction}; #[test] @@ -200,7 +211,10 @@ mod tests { -45, {}, true - ] + ], + "7.3": "random text", + "100": 1000, + "24": 42 } "#}; @@ -217,6 +231,14 @@ mod tests { 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!("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 = extra.as_object().unwrap(); From 70c74224fae8178a257b757bafcd42996a14b4d3 Mon Sep 17 00:00:00 2001 From: Nikita-str Date: Sun, 29 Sep 2024 07:26:28 +0300 Subject: [PATCH 2/2] some refactoring --- .../src/value/conversions/serde_json.rs | 34 +++++++------------ 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/core/engine/src/value/conversions/serde_json.rs b/core/engine/src/value/conversions/serde_json.rs index 09dbf5e3ced..95bbd5e884f 100644 --- a/core/engine/src/value/conversions/serde_json.rs +++ b/core/engine/src/value/conversions/serde_json.rs @@ -124,38 +124,30 @@ impl JsValue { .with_message("cannot convert bigint to JSON") .into()), 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() { let len = obj.length_of_array_like(context)?; let mut arr = Vec::with_capacity(len as usize); - let obj = obj.borrow(); - for k in 0..len as u32 { - let val = obj.properties().get(&k.into()).map_or(Self::Null, |desc| { - desc.value().cloned().unwrap_or(Self::Null) - }); - arr.push(val.to_json(context)?); + let val = value_by_prop_key(k.into(), context)?; + arr.push(val); } Ok(Value::Array(arr)) } else { let mut map = Map::new(); - let mut value_by_prop_key = |property_key| match obj - .borrow() - .properties() - .get(&property_key) - .and_then(|x| x.value().cloned()) - { - Some(val) => val.to_json(context), - None => Ok(Value::Null), - }; for index in obj.borrow().properties().index_property_keys() { let key = index.to_string(); - - let property_key = PropertyKey::from(index); - let value = value_by_prop_key(property_key)?; - + let value = value_by_prop_key(index.into(), context)?; map.insert(key, value); } @@ -169,9 +161,7 @@ impl JsValue { .into()) } }; - - let value = value_by_prop_key(property_key)?; - + let value = value_by_prop_key(property_key, context)?; map.insert(key, value); }