Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to deserialize arbitrary JSON using Serde without creating fine-grained objects?

Tags:

json

rust

serde

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"));
}
like image 602
Shepmaster Avatar asked Mar 03 '18 00:03

Shepmaster


People also ask

Is Serde fast?

Serde. Serde, the incumbent serialization/deserialization library, is elegant, flexible, fast to run, and slow to compile.

What is Serde JSON?

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" ] }

Is Serde slow?

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.

How does Serde work rust?

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.


1 Answers

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"));
}
like image 171
Shepmaster Avatar answered Oct 13 '22 20:10

Shepmaster