Skip to content

Commit fd693ad

Browse files
committed
WIp wasm-bindgen serde-serialize
1 parent de1bc93 commit fd693ad

File tree

4 files changed

+32
-22
lines changed

4 files changed

+32
-22
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vm/src/stdlib/json.rs

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,17 @@ use num_traits::cast::ToPrimitive;
1919

2020
// We need to have a VM available to serialise a PyObject based on its subclass, so we implement
2121
// PyObject serialisation via a proxy object which holds a reference to a VM
22-
struct PyObjectSerializer<'s> {
22+
pub struct PyObjectSerializer<'s> {
2323
pyobject: &'s PyObjectRef,
2424
vm: &'s VirtualMachine,
2525
}
2626

2727
impl<'s> PyObjectSerializer<'s> {
28-
fn clone_with_object(&self, pyobject: &'s PyObjectRef) -> PyObjectSerializer {
28+
pub fn new(vm: &'s VirtualMachine, pyobject: &'s PyObjectRef) -> PyObjectSerializer<'s> {
29+
PyObjectSerializer { pyobject, vm }
30+
}
31+
32+
pub fn clone_with_object(&self, pyobject: &'s PyObjectRef) -> PyObjectSerializer {
2933
PyObjectSerializer {
3034
pyobject,
3135
vm: self.vm,
@@ -83,10 +87,16 @@ impl<'s> serde::Serialize for PyObjectSerializer<'s> {
8387
// This object is used as the seed for deserialization so we have access to the PyContext for type
8488
// creation
8589
#[derive(Clone)]
86-
struct PyObjectDeserializer<'c> {
90+
pub struct PyObjectDeserializer<'c> {
8791
vm: &'c VirtualMachine,
8892
}
8993

94+
impl PyObjectDeserializer<'_> {
95+
fn new(vm: &VirtualMachine) -> PyObjectDeserializer<'_> {
96+
PyObjectDeserializer { vm }
97+
}
98+
}
99+
90100
impl<'de> serde::de::DeserializeSeed<'de> for PyObjectDeserializer<'de> {
91101
type Value = PyObjectRef;
92102

@@ -188,31 +198,31 @@ impl<'de> Visitor<'de> for PyObjectDeserializer<'de> {
188198
}
189199
}
190200

191-
pub fn ser_pyobject(vm: &mut VirtualMachine, obj: &PyObjectRef) -> serde_json::Result<String> {
192-
let serializer = PyObjectSerializer { pyobject: obj, vm };
193-
serde_json::to_string(&serializer)
194-
}
195-
196-
pub fn de_pyobject(vm: &mut VirtualMachine, s: &str) -> serde_json::Result<PyObjectRef> {
197-
let de = PyObjectDeserializer { vm };
198-
// TODO: Support deserializing string sub-classes
199-
de.deserialize(&mut serde_json::Deserializer::from_str(s))
200-
}
201-
202201
/// Implement json.dumps
203202
fn json_dumps(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
204203
// TODO: Implement non-trivial serialisation case
205204
arg_check!(vm, args, required = [(obj, None)]);
206-
let string = ser_pyobject(vm, obj).map_err(|err| vm.new_type_error(err.to_string()))?;
205+
let res = {
206+
let serializer = PyObjectSerializer::new(vm, obj);
207+
serde_json::to_string(&serializer)
208+
};
209+
let string = res.map_err(|err| vm.new_type_error(format!("{}", err)))?;
207210
Ok(vm.context().new_str(string))
208211
}
209212

210213
/// Implement json.loads
211214
fn json_loads(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
212215
// TODO: Implement non-trivial deserialization case
213216
arg_check!(vm, args, required = [(string, Some(vm.ctx.str_type()))]);
214-
215-
de_pyobject(vm, &objstr::get_value(&string)).map_err(|err| {
217+
let res = {
218+
let de = PyObjectDeserializer::new(vm);
219+
// TODO: Support deserializing string sub-classes
220+
de.deserialize(&mut serde_json::Deserializer::from_str(&objstr::get_value(
221+
&string,
222+
)))
223+
};
224+
225+
res.map_err(|err| {
216226
let json_decode_error = vm
217227
.sys_module
218228
.get_item("modules")

wasm/lib/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ crate-type = ["cdylib", "rlib"]
1414
rustpython_parser = { path = "../../parser" }
1515
rustpython_vm = { path = "../../vm" }
1616
cfg-if = "0.1.2"
17-
wasm-bindgen = "0.2"
17+
wasm-bindgen = { version = "0.2", features = ["serde-serialize"] }
1818
wasm-bindgen-futures = "0.3"
1919
js-sys = "0.3"
2020
futures = "0.1"

wasm/lib/src/convert.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,8 @@ pub fn py_to_js(vm: &mut VirtualMachine, py_obj: PyObjectRef) -> JsValue {
130130
}
131131
arr.into()
132132
} else {
133-
match rustpython_vm::stdlib::json::ser_pyobject(vm, &py_obj) {
134-
Ok(json) => js_sys::JSON::parse(&json).unwrap_or(JsValue::UNDEFINED),
135-
Err(_) => JsValue::UNDEFINED,
136-
}
133+
let ser = rustpython_vm::stdlib::json::PyObjectSerializer::new(vm, &py_obj);
134+
JsValue::from_serde(&ser).unwrap_or(JsValue::UNDEFINED)
137135
}
138136
}
139137

0 commit comments

Comments
 (0)