-
Notifications
You must be signed in to change notification settings - Fork 285
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
RFC: serde
implementation for Neon
#701
Conversation
Hi @kjvalencik. Thank your for this PR (and all the other work that you are doing on I stumbled across this whilst looking for an update on how to use Since this is tagged "RFC" I thought I'd answer some of your questions (the ones that I fell that I am able to):
I agree
👍🏽 Both seem good to me.
This sounds really useful. I'm an noobie Rust programmer, but please do let me know if you think there is anything I can do to help with this PR. |
@nokome Thanks for the feedback! FYI, serializing as JSON is a perfectly valid way to transfer complicated structs. In fact, because the overhead of calling into V8 is so high for most data it's much faster to serialize to JSON than it is to go directly between Rust and JS data types, which is pretty surprising! The only exception would be structs that include large binary types like |
Thanks @kjvalencik, that's really useful to know! |
@kjvalencik so if we have a struct Noting this is my use case: pub struct DataItem {
owner: String,
tags: Vec<(String, String)>,
data: Bytes
} where |
@joshbenaron Binary data is about the only time transcoding directly is faster than JSON serialization. For this specific example, my recommendation would be to serialize the An advantage of this approach over using For example: #[derive(Serialize)]
pub struct DataItem {
owner: String,
tags: Vec<(String, String)>,
#[serde(skip)]
// This field is skipped and not included when serialized
data: Bytes
}
// DataItem can be serialized and parsed as JSON, but won't include `data`
// `data` gets sent separately as an `ArrayBuffer`
let data = ArrayBuffer::external(&mut cx, item.data); |
@kjvalencik Ah I see. So just to clarify, is |
@joshbenaron Yep, sorry about the incorrect name there. |
@kjvalencik Thanks for all your help! What about going from JS -> Rust. Should I split up |
@joshbenaron Same goes for the other direction (JS to Rust). I do have a couple follow-up questions.
|
@kjvalencik in fact 10GB can be small. Essentially I have some JSON which has some data which can be any size. could be a petabyte. I create a signature based on all the fields and encode the JSON to binary using And yes, JS preprocesses the data before going into Rust |
@joshbenaron This is a limit of the V8 engine. The default heap size is 1.5GB. You cannot allocated more than this on the heap. |
|
Yeah, that's the parameter to override. |
f0e0b3b
to
61636ca
Compare
Neon Serde
Why
Users would like an ergonomic way of converting between Rust and JavaScript types without serialization.
Prior work can be found in the community maintained
neon-serde
crate.What
Serializer
andDeserializer
are implemented inneon-runtime
instead of inneon
for performance. It allows us to verify safety in a single place instead of in all operations. Further explanation is given in the module documentation.Questions
Error
type? CurrentlySerdeError
, but includingserde
in the name doesn't feel great.Error
andDisplay
NeonResult
withor_throw
JavaScript
exceptionResultExt
is is a superset of the functionality ofJsResultExt
. We may have overlappingimpl
issues if we try to support both. We may want to eventually deprecate and removeJsResultExt
to_js_value
andfrom_js_value
toContext
. What are the thoughts on these names?JsValue
to theValue
trait for easy chaining? Not sure what to call it.let data: MyData = cx.argument::<JsValue>(0)?.deserialize(&mut cx).or_throw(&mut cx)?;
Future Expansion
impl
ofResultExt
cx.argument
that reduces the noise.let data: MyData = cx.argument_from_value(0)?;