Reputation: 1595
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
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
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