Modify one field of type Option<serde_json::Value> in a struct

Hello,

Facing difficulties updating one field in a struct of type Option<serde_json::Value>.

Here is the sample scenario.

use serde::{Deserialize, Serialize};
use serde_json::Value;

#[derive(PartialEq, Debug, Clone, Serialize, Deserialize, Default)]
pub struct Person {
  pub user_id: String,
  pub details: Option<Value>
}

After receiving the value of the person I want to add some static value in the details field.
Say, below is the input I got from user:

Person {
   user_id: "user12345",
   details:Some(
            Object({
                "email": String("test@user.com"),
            }),
        )
}

I want to modify it to something like below:

Person {
   user_id: "user12345",
   details:Some(
            Object({
               "email": String("test@user.com"),
               "channel": String("web"),
               "version": String("1.0.1")
            }),
        )
} 

How do I do that?

Please surround your code with ``` to get appropriate formatting:

FYI, you can use the pencil-shaped edit button under any post that you made to edit your own post.

Thank you for the suggestion.

1 Like

Thank you.

You can achieve what you asked for like this:

let mut person: Person = get_value_from_user();
if let Some(Value::Object(obj)) = &mut person.details {
    obj.extend([ // note: requires fairly recent (stable) Rust, otherwise arrays are not `IntoIterator`
        ("channel".to_owned(), "web".into()),
        ("version".to_owned(), "1.0.1".into()),
    ]);
}

This will leave person unmodified unless the details field matches Some(Value::Object(_)). It will also replace existing entries whose key is "channel" or "version", if there are any.

Most likely there's a better (more idiomatic and less of a pain to work with) solution here where you take advantage of Serde to deserialize into your own struct instead of a weakly-typed Value.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.