How do I use `serde_json_core` to deserialise an array without allocations?

Viewed 291

How can I deserialise JSON {"arr":[1,2,3,4]} without performing a heap allocation using serde_json_core or similar? It performs one allocation currently. I see serde_json_core uses the heapless crate but I am unsure exactly how to make them work together.

#[derive(Deserialize)]
struct MyStruct {
    arr: Vec<u64>,
}

fn main() {
    let j = r#"{"arr":[1,2,3,4]}"#;

    let r: serde_json_core::de::Result<(MyStruct, usize)> = serde_json_core::from_str(j);
    let (out, _) = r.unwrap();

    println!("First value: {}.",  out.arr[0]);
}

I am using serde_json_core = 0.4.0.

1 Answers

The serde-json-core crate can deserialize JSON arrays into any type that implements the Deserialize trait. If you want to avoid memory allocations, you need to pick a container that does not allocate.

If the size of the array is known in advance, you can simply use a fixed-sized array, i.e. [T; N]. This will return a deserialization error if the size of JSON array is not exactly N.

If the size of the JSON array is variable with a known upper limit, you can use one of various vector-like stack-allocated datastructures. One such option is the heapless::Vec, which implements Deserialize if you enable the serde feature for heapless. In your Cargo.yaml file, you can do this like this:

heapless = { version = "0.7", features = ["serde"] }

If you use the same version of heapless that your version of serde-json-core depends on, it will only be included in your build once.

Related