Serde_json Values access

Hi,

I come across the following code in the serde_json documentation.

`use serde_json::{Result, Value};

fn untyped_example() -> Result<()> {
// Some JSON input data as a &str. Maybe this comes from the user.
let data = r#"
{
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
}"#;

// Parse the string of data into serde_json::Value.
let v: Value = serde_json::from_str(data)?;

// Access parts of the data by indexing with square brackets.
println!("Please call {} at the number {}", v["name"], v["phones"][0]);

Ok(())  

}
``
The thing I need explanation is this.
println!("Please call {} at the number {}", v["name"], v["phones"][0]);
Why I'm accessing the Value enum using square brackets. What the syntax logic
behind that.

Next question is this

What is this syntax r# ?

let data = r#" { "name": "John Doe", "age": 43, "phones": [ "+44 1234567", "+44 2345678" ] }"#;
May please help.

Thanks,
S.Gopinath

Hi,

I come across the following code in the serde_json documentation.

use serde_json::{Result, Value};

fn untyped_example() -> Result<()> {
// Some JSON input data as a &str. Maybe this comes from the user.
let data = r#"
{
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
]
}"#;

// Parse the string of data into serde_json::Value.
let v: Value = serde_json::from_str(data)?;

// Access parts of the data by indexing with square brackets.
println!("Please call {} at the number {}", v["name"], v["phones"][0]);

Ok(())  
}

The thing I need explanation is this.


println!("Please call {} at the number {}", v["name"], v["phones"][0]);

Why I'm accessing the Value enum using square brackets. What the syntax logic
behind that.

Next question is this

What is this syntax r# ?

let data = r#" { "name": "John Doe", "age": 43, "phones": [ "+44 1234567", "+44 2345678" ] }"#;

May please help.

Thanks,
S.Gopinath

The serde_json crate wraps all supported values in an enum, called Value. The Value enum can contain all valid json values: map/object, numbers, strings, boolean, list or null.
Some of these object implement the Index operator trait which allows accessing data like this:

let v: Value = v["name"];

So v["phones"][0] first indexes into Value::Object with key "phones" to get Value::Array and accesses the first number in the list, which is a Value::String.

The r#" some string"# is the raw string syntax. It allows you to escape anything within the r#""# as long as the number of #s in the beginning match the number of them at the end.

let s: &str = r#####"
Hello,
What is the serial #?
"#####;

Thanks.

I see serde_json::Map implements index trait.

Suppose I do not know whats the value of Key (as I receive just a json from the server),
I want to print the key (type is String) and I want to print or assign the value (which is of type Value).
How to do that ?

Thanks,
S.Gopinath

Value::Map is an enum variant type that wraps HashMap<String, Value>, so you can use it just like an ordinary HashMap.

I'd like to suggest you to parse the json object by deriving structs instead of manipulating Values, It is more performant and easier to use.
So, the object above can be parsed like this:

use serde::Deserialize;

#[derive(Deserialize)]
struct Person {
    name: String,
    age: u32,
    phones: Vec<String>,
}

fn main() {
    let mut person: Person = serde_json::from_str(r#"{"name": "John Doe", "age": 43, "phones": ["+44 1234567", "+44 2345678"]}"#).unwrap();
    println!("Please call {} at {}", person.name, &person.phones[0]);

    // add number
    person.phones.push("+44 3456789".to_string());
    // print all phones
    println!("{:?}", &person.phones);
}

You can use most of Rust's standard library with serde for both Serialize and Deserialization.

Thanks..

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.