andrey
andrey

Reputation: 1595

Decoding a variable-length JSON array into a Rust array

I'm trying to decode this data:

{
  "ok": true,
  "people": [
    {
      "name": "John",
      "age": "10"
    }
  ]
}

Into a struct.The code is:

extern crate rustc_serialize;

use rustc_serialize::json;

#[derive(RustcDecodable)]
struct Man {
    name: String,
    age: i32,
}

#[derive(RustcDecodable)]
struct Men {
    ok:      bool,
    people: [Man; 16],
}

...

let json: Men = json::decode(&data).unwrap();

...

The problem is that when the length of the array in Men doesn't match the length of corresponding field in JSON exactly, this error happens:

thread '<main>' panicked at 'called `Result::unwrap()`
on an `Err` value: ApplicationError("wrong array length")',
../src/libcore/result.rs:738

Any ideas on how to deal with this? General code style advice is also welcome.

Upvotes: 1

Views: 2058

Answers (2)

Emilia Bopp
Emilia Bopp

Reputation: 883

Well, either you really have only lists of men with length 1, in that case you could change the type to people: [Man; 1]. Or you actually have variable length at run-time, in which case you'd be better off picking a dynamically sized vector like people: Vec<Man>.

As a hint: serde and serde_json might be better choices as dependencies, since rustc-serialize was only extracted from the compiler, so that it would not have to end up in std permanently.

Upvotes: 4

Shepmaster
Shepmaster

Reputation: 431449

Having an array that is only partially filled doesn't really make sense. Arrays statically know exactly how much space to allocate, but you have to fill that space with something in avoid some security issues with uninitialized data. They have no concept of "unused" spots.

The easiest fix is to use a Vec:

#[derive(RustcDecodable)]
struct Men {
    ok:     bool,
    people: Vec<Man>,
}

A Vec represents a resizable contiguous amount of data. It knows how much space is allocated and how many of those allocations are valid, and will never let you access the invalid items.

Upvotes: 6

Related Questions