Rust `value borrowed here after move` when setting to Map

Viewed 747

I want to put an object in a serde_json::Map where the key will be a value from inside that object.

use serde_json::{json, Map, Value};

fn main() {
    let a = json!({
        "x": "y"
    });
    
    let mut d: Map<String, Value> = Map::new();
    d[&a["x"].to_string()] = a;
}

Error:

borrow of moved value: `a`
value borrowed here after moverustcE0382
main.rs(9, 30): value moved here
main.rs(4, 9): move occurs because `a` has type `Value`, which does not implement the `Copy` trait
2 Answers

Even if you solve this lifetime issue, the IndexMut implementation for Map cannot be used for inserting new elements into a map. It panics if the given key is not present.

Use the insert() method instead, which solves both problems:

d.insert(a["x"].to_string(), a);

Since the proper solution has already been answered, I am going to cover another perspective on this,

d[&a["x"].to_string()] = a;

Even if the mentioned bit panics when there is no entry against the passed index, what it is really saying is that, get me the value at index x and replace it with a, = is invoking Copy here, since a doesn't doesn't implement Copy trait the compiler is giving you error.

In the following case, a is simply moved, so no Copy is invoked.

d.insert(a["x"].to_string(), a);

Also, the equivalent in your case may be get or insert.

let entry = d.entry(a["x"].to_string()).or_insert(a);

To access the value from entry you just deref it as *entry

Related