-
Notifications
You must be signed in to change notification settings - Fork 154
Parsing framework for javascript objects (serde without the string step) #69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This seems very similar to what we have been suggesting / considering for cc @RReverser, who actually investigated this further and had some interesting performance results: rustwasm/wasm-bindgen#1258 (comment) Unless we end up with something that is fundamentally incompatible with |
Using serde would be preferable :). |
In the course of this work and one of the discussions in #53 I actually started thinking of a vague proposal for object passing that could be still useful with or without serde integration, but it's not fully formed to write down yet... |
This now already exists, with a wasm-bindgen note: https://github.com/rustwasm/wasm-bindgen/pull/1553/files. |
@derekdreery Oh yeah, I built it but didn't reference here. Thanks! |
Summary
Provide a serialization and deserialization framework for converting between javascript values (
wasm_bindgen::JsValue
) and rust values.Related proposals:
Motivation
Currently, there are a few different ways to work with javascript values, but they are all sub-optimal.
Case 1:
extern type
&JsCast
I guess this is the low-level way of working with javascript objects. We don't use reflection like
js_sys::Object
orjs_sys::Reflect
. If we usedyn_into
, we will get aninstanceof
check, but there is no check that the values we define in the#[wasm_bindgen]
extern block actually match the properties the javascript object contains.Case 2:
js_sys::Object
andjs_sys::Reflect
These types provide reflection - we can check to see if an object has a property or not. This is a good pragmatic safe way of providing a checked gateway into the typesafe rust land. If we check for all parameters we expect, there is probably some overhead, but we know the values we create in rust are correct and we can avoid panics. TODO I need to understand better what happens if you import a non-existant property in a wasm-bindgen extern block.
Case 3:
JsValue::{from/into}_serde
In this case we just convert our javascript type into a string and then re-parse it using the awesome serde framework. This is a reliable way to check we get exactly what we want, but has the following downsides:
JSON.stringify
. For example, we can't hold javascript functions, and we lose type information converting objects into json.This proposal aims to provide fine-grained control of parsing exactly what you want to, leaving opaque what you want to, and doing it all without going through a string.
Detailed Explanation
What follows is just my early thoughts on how this might work. It needs iteration.
The serde framework provides a great template for how to generate serialization and deserialization code. I would envisage this working like
There is some complexity from the fact that we do different things for different types, and special case types from wasm_bindgen/js_sys. For a JsValue, we just have to check the object has a property and then get a handle on the property, for functions, we would check in js that the object is a function, and then for actual objects we use reflection to check the properties are there and then copy them (or a handle for complex objects) into rust.
Drawbacks, Rationale, and Alternatives
The main drawback of this is it's probably a lot of work to implement.
We also already have all the options above, so we could use them, or develop something like gloo-properties. We could possibly build this on top of something like gloo-properties - maybe that would decrease complexity.
Prior art
Unresolved Questions
Basically everything about this. Is it a good idea? How would we implement it? I feel its quite ambitious & complex.
The text was updated successfully, but these errors were encountered: