proper handling of Json objects in Python and JS

main
Ziyang Hu 1 year ago
parent 5488e66c18
commit 3a413799f8

@ -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::<JsBuffer, _>(cx) {
let d = b.as_slice(cx);
*coll = DataValue::Bytes(d.to_vec());
} else if let Ok(obj) = val.downcast::<JsObject, _>(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::<JsString, _>(cx)?.value(cx);
let v = obj.get(cx, &name)?.downcast::<JsValue, _>(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);

@ -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> {
}
DataValue::List(coll)
} else if let Ok(d) = ob.downcast::<PyDict>() {
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"

Loading…
Cancel
Save