I have a JSON object that contains a few metadata keys and a large data payload. My service cares about the metadata for the purposes of logging and routing, but does not care about the payload, other than to pass the payload off to another service. I will never need to look inside the payload for any reason.
Right now, the payload is represented in my struct as aserde_json::Value
. Through profiling, I've seen the (de)serialization of the Value
takes a non-trivial amount of time.
Is there a mechanism in Serde where I can bundle around the payload without having to pay the cost of deserializing it into component values only to be required to re-serialize them later?
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
#[derive(Serialize, Deserialize)]
struct DataBlob<'a> {
id: &'a str,
priority: u8,
// payload: OpaqueValue,
}
fn main() {
let input = r#"{
"id": "cat",
"priority": 42,
"payload": [1, 2, 3, 4]
}"#;
let parsed = serde_json::from_str::<DataBlob>(input).expect("Could not deserialize");
let output = serde_json::to_string(&parsed).expect("Could not serialize");
assert!(output.contains("payload"));
}
Serde. Serde, the incumbent serialization/deserialization library, is elegant, flexible, fast to run, and slow to compile.
Serde JSON JSON is a ubiquitous open-standard format that uses human-readable text to transmit data objects consisting of key-value pairs. { "name": "John Doe", "age": 43, "address": { "street": "10 Downing Street", "city": "London" }, "phones": [ "+44 1234567", "+44 2345678" ] }
Serde is really designed to be fast, by allowing fully statically dispatched operations without runtime reflections so formats and types are decoupled at code but transparent to the optimization. It's serde_json which cares all the weirdnesses of the JSON format.
Serde is a framework for serializing and deserializing Rust data structures efficiently and generically. The Serde ecosystem consists of data structures that know how to serialize and deserialize themselves along with data formats that know how to serialize and deserialize other things.
This was added in serde_json 1.0.29 as the type RawValue
. It must be enabled using the raw_value
feature and then placed behind a reference:
extern crate serde; // 1.0.79
#[macro_use]
extern crate serde_derive; // 1.0.79
extern crate serde_json; // 1.0.30, features = ["raw_value"]
#[derive(Serialize, Deserialize)]
struct DataBlob<'a> {
id: &'a str,
priority: u8,
payload: &'a serde_json::value::RawValue,
}
fn main() {
let input = r#"{
"id": "cat",
"priority": 42,
"payload": [1, 2, 3, 4]
}"#;
let parsed = serde_json::from_str::<DataBlob>(input).expect("Could not deserialize");
let output = serde_json::to_string(&parsed).expect("Could not serialize");
assert!(output.contains("payload"));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With