Borrow solution for this case



I have the following borrow problem when trying to truncate a json::Array to 2 in length using cargo:json
I have a “fix” but I wondered what would be the ideal solution here. I have commented the borrow problems. There may also be another way to truncate the array, however I’d like to get the chosen method working first.

let first_two = op["operationStatuses"].members().take(2).cloned(); // Immutable borrow on "op"
let new_statuses = first_two.collect::<Vec<json::JsonValue>>();
op["operationStatuses"] = new_statuses.into(); // Mutable borrow on "op"

let os = op[“operationStatuses”].clone(); // Clone must be separate let statement
let first_two = os.members().take(2).cloned();
let new_statuses = first_two.collect::<Vecjson::JsonValue>();
op[“operationStatuses”] = new_statuses.into();

Other methods I’ve thought of could include Slicing a clone instead, or a filter predicate, which I will investigate shortly.


You may find it easier to implement this using a strongly typed data structure rather than something like JsonValue. Once you have a struct where operationStatuses is just a Vec, it only requires calling Vec::truncate to truncate the length. The code is more readable and you get better error messages if the JSON input does not match the shape that your program assumes.

extern crate serde_derive;
extern crate serde_json;

use serde_json::Value;

#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct Murk {
    operation_statuses: Vec<Value>,

fn main() {
    let j = "{\"operationStatuses\":[1, 2, 3, 4, 5, 6]}";
    let mut op: Murk = serde_json::from_str(j).unwrap();

    // Truncate Vec to at most two elements.

    println!("{:?}", op);