From 3a413799f8620aef3e859adacd6202efb4c73e19 Mon Sep 17 00:00:00 2001 From: Ziyang Hu Date: Thu, 4 May 2023 17:30:09 +0800 Subject: [PATCH] proper handling of Json objects in Python and JS --- cozo-lib-nodejs/src/lib.rs | 12 ++++++++++++ cozo-lib-python/src/lib.rs | 15 ++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/cozo-lib-nodejs/src/lib.rs b/cozo-lib-nodejs/src/lib.rs index 53f1adca..2ff01d84 100644 --- a/cozo-lib-nodejs/src/lib.rs +++ b/cozo-lib-nodejs/src/lib.rs @@ -15,6 +15,7 @@ use lazy_static::lazy_static; use miette::{miette, Result}; use neon::prelude::*; use neon::types::buffer::TypedArray; +use serde_json::json; use cozo::*; @@ -79,6 +80,17 @@ fn js2value<'a>( } else if let Ok(b) = val.downcast::(cx) { let d = b.as_slice(cx); *coll = DataValue::Bytes(d.to_vec()); + } else if let Ok(obj) = val.downcast::(cx) { + let names = obj.get_own_property_names(cx)?; + let mut coll_inner = serde_json::Map::default(); + for i in 0..names.len(cx) { + let name = names.get(cx, i)?.downcast::(cx)?.value(cx); + let v = obj.get(cx, &name)?.downcast::(cx)?; + let mut target = DataValue::Bot; + js2value(cx, v, &mut target)?; + coll_inner.insert(name, serde_json::Value::from(target)); + } + *coll = DataValue::Json(JsonData(json!(coll_inner))); } else { let err = cx.string("Javascript value cannot be converted."); return cx.throw(err); diff --git a/cozo-lib-python/src/lib.rs b/cozo-lib-python/src/lib.rs index 653a3de5..11bbe8d7 100644 --- a/cozo-lib-python/src/lib.rs +++ b/cozo-lib-python/src/lib.rs @@ -13,6 +13,7 @@ use miette::{IntoDiagnostic, Report, Result}; use pyo3::exceptions::PyException; use pyo3::prelude::*; use pyo3::types::{PyBytes, PyDict, PyList, PyString, PyTuple}; +use serde_json::json; use cozo::*; @@ -61,13 +62,17 @@ fn py_to_value(ob: &PyAny) -> PyResult { } DataValue::List(coll) } else if let Ok(d) = ob.downcast::() { - let mut coll = Vec::with_capacity(d.len()); + let mut coll = serde_json::Map::default(); for (k, v) in d { - let k = py_to_value(k)?; - let v = py_to_value(v)?; - coll.push(DataValue::List(vec![k, v])) + let k = serde_json::Value::from(py_to_value(k)?); + let k = match k { + serde_json::Value::String(s) => s, + s => s.to_string(), + }; + let v = serde_json::Value::from(py_to_value(v)?); + coll.insert(k, v); } - DataValue::List(coll) + DataValue::Json(JsonData(json!(coll))) } else { return Err(PyException::new_err(format!( "Cannot convert {ob} into Cozo value"