Skip to content

Commit 0ac42ac

Browse files
committed
Add convenience functions
1 parent 9ac854a commit 0ac42ac

File tree

4 files changed

+50
-32
lines changed

4 files changed

+50
-32
lines changed

vm/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ mod frozen;
5353
pub mod function;
5454
pub mod import;
5555
pub mod obj;
56+
pub mod py_serde;
5657
mod pyhash;
5758
pub mod pyobject;
58-
pub mod ser_de;
5959
pub mod stdlib;
6060
mod sysmodule;
6161
mod traceback;

vm/src/ser_de.rs renamed to vm/src/py_serde.rs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use std::fmt;
22

33
use serde;
4-
use serde::de::Visitor;
5-
use serde::ser::{SerializeMap, SerializeSeq};
4+
use serde::de::{DeserializeSeed, Visitor};
5+
use serde::ser::{Serialize, SerializeMap, SerializeSeq};
66

77
use crate::obj::{
88
objbool,
@@ -15,6 +15,29 @@ use crate::pyobject::{IdProtocol, ItemProtocol, PyObjectRef, TypeProtocol};
1515
use crate::VirtualMachine;
1616
use num_traits::cast::ToPrimitive;
1717

18+
#[inline]
19+
pub fn serialize<S>(
20+
vm: &VirtualMachine,
21+
pyobject: &PyObjectRef,
22+
serializer: S,
23+
) -> Result<S::Ok, S::Error>
24+
where
25+
S: serde::Serializer,
26+
{
27+
PyObjectSerializer { vm, pyobject }.serialize(serializer)
28+
}
29+
30+
#[inline]
31+
pub fn deserialize<'de, D>(
32+
vm: &'de VirtualMachine,
33+
deserializer: D,
34+
) -> Result<<PyObjectDeserializer as DeserializeSeed>::Value, D::Error>
35+
where
36+
D: serde::Deserializer<'de>,
37+
{
38+
PyObjectDeserializer { vm }.deserialize(deserializer)
39+
}
40+
1841
// We need to have a VM available to serialise a PyObject based on its subclass, so we implement
1942
// PyObject serialisation via a proxy object which holds a reference to a VM
2043
pub struct PyObjectSerializer<'s> {
@@ -24,7 +47,7 @@ pub struct PyObjectSerializer<'s> {
2447

2548
impl<'s> PyObjectSerializer<'s> {
2649
pub fn new(vm: &'s VirtualMachine, pyobject: &'s PyObjectRef) -> Self {
27-
PyObjectSerializer { pyobject, vm }
50+
PyObjectSerializer { vm, pyobject }
2851
}
2952

3053
fn clone_with_object(&self, pyobject: &'s PyObjectRef) -> PyObjectSerializer {
@@ -97,7 +120,7 @@ impl<'c> PyObjectDeserializer<'c> {
97120
}
98121
}
99122

100-
impl<'de> serde::de::DeserializeSeed<'de> for PyObjectDeserializer<'de> {
123+
impl<'de> DeserializeSeed<'de> for PyObjectDeserializer<'de> {
101124
type Value = PyObjectRef;
102125

103126
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>

vm/src/stdlib/json.rs

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,36 @@
11
use crate::obj::objstr::PyStringRef;
2+
use crate::py_serde;
23
use crate::pyobject::{create_type, ItemProtocol, PyObjectRef, PyResult};
3-
use crate::ser_de::{PyObjectDeserializer, PyObjectSerializer};
44
use crate::VirtualMachine;
5-
use serde::de::DeserializeSeed;
65
use serde_json;
76

87
/// Implement json.dumps
98
pub fn json_dumps(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<String> {
10-
let serializer = PyObjectSerializer::new(vm, &obj);
9+
let serializer = py_serde::PyObjectSerializer::new(vm, &obj);
1110
serde_json::to_string(&serializer).map_err(|err| vm.new_type_error(err.to_string()))
1211
}
1312

1413
/// Implement json.loads
1514
pub fn json_loads(string: PyStringRef, vm: &VirtualMachine) -> PyResult {
1615
// TODO: Implement non-trivial deserialization case
16+
let de_result =
17+
py_serde::deserialize(vm, &mut serde_json::Deserializer::from_str(string.as_str()));
1718

18-
let de = PyObjectDeserializer::new(vm);
19-
20-
// TODO: Support deserializing string sub-classes
21-
de.deserialize(&mut serde_json::Deserializer::from_str(string.as_str()))
22-
.map_err(|err| {
23-
let module = vm
24-
.get_attribute(vm.sys_module.clone(), "modules")
25-
.unwrap()
26-
.get_item("json", vm)
27-
.unwrap();
28-
let json_decode_error = vm.get_attribute(module, "JSONDecodeError").unwrap();
29-
let json_decode_error = json_decode_error.downcast().unwrap();
30-
let exc = vm.new_exception(json_decode_error, format!("{}", err));
31-
vm.set_attr(&exc, "lineno", vm.ctx.new_int(err.line()))
32-
.unwrap();
33-
vm.set_attr(&exc, "colno", vm.ctx.new_int(err.column()))
34-
.unwrap();
35-
exc
36-
})
19+
de_result.map_err(|err| {
20+
let module = vm
21+
.get_attribute(vm.sys_module.clone(), "modules")
22+
.unwrap()
23+
.get_item("json", vm)
24+
.unwrap();
25+
let json_decode_error = vm.get_attribute(module, "JSONDecodeError").unwrap();
26+
let json_decode_error = json_decode_error.downcast().unwrap();
27+
let exc = vm.new_exception(json_decode_error, format!("{}", err));
28+
vm.set_attr(&exc, "lineno", vm.ctx.new_int(err.line()))
29+
.unwrap();
30+
vm.set_attr(&exc, "colno", vm.ctx.new_int(err.column()))
31+
.unwrap();
32+
exc
33+
})
3734
}
3835

3936
pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {

wasm/lib/src/convert.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use js_sys::{Array, ArrayBuffer, Object, Promise, Reflect, Uint8Array};
22
use num_traits::cast::ToPrimitive;
3-
use serde::{de::DeserializeSeed, ser::Serialize};
43
use serde_wasm_bindgen;
54
use wasm_bindgen::{closure::Closure, prelude::*, JsCast};
65

76
use rustpython_vm::function::PyFuncArgs;
87
use rustpython_vm::obj::{objbytes, objint, objsequence, objtype};
8+
use rustpython_vm::py_serde;
99
use rustpython_vm::pyobject::{ItemProtocol, PyObjectRef, PyResult, PyValue};
1010
use rustpython_vm::VirtualMachine;
1111

@@ -132,8 +132,7 @@ pub fn py_to_js(vm: &VirtualMachine, py_obj: PyObjectRef) -> JsValue {
132132
view.slice(0, bytes.len() as u32).into()
133133
}
134134
} else {
135-
rustpython_vm::ser_de::PyObjectSerializer::new(vm, &py_obj)
136-
.serialize(&serde_wasm_bindgen::Serializer::new())
135+
py_serde::serialize(vm, &py_obj, &serde_wasm_bindgen::Serializer::new())
137136
.unwrap_or(JsValue::UNDEFINED)
138137
}
139138
}
@@ -225,8 +224,7 @@ pub fn js_to_py(vm: &VirtualMachine, js_val: JsValue) -> PyObjectRef {
225224
// Because `JSON.stringify(undefined)` returns undefined
226225
vm.get_none()
227226
} else {
228-
rustpython_vm::ser_de::PyObjectDeserializer::new(vm)
229-
.deserialize(serde_wasm_bindgen::Deserializer::from(js_val))
227+
py_serde::deserialize(vm, serde_wasm_bindgen::Deserializer::from(js_val))
230228
.unwrap_or_else(|_| vm.get_none())
231229
}
232230
}

0 commit comments

Comments
 (0)