Parsing String to i32 not working

I try to parse a String from serde_json::Value into a i32 and I'm always getting a InvalidDigit error.

called `Result::unwrap()` on an `Err` value: ParseIntError { kind: InvalidDigit }
let val: &Value = new_json.get("id").unwrap();
let string_id: String = serde_json::to_string(val).unwrap();
let id: i32 = string_id.trim().parse::<i32>().unwrap();

What is the content of the string? What is the value of val?

Note that your snippet looks a little suboptimal. You can convert Value to string directly as it implements Display and hence has a Value::to_string method, so using serde_json::to_string can be avoided. If your val is a Value::String variant, you can also extract the contained string directly, without allocation.

1 Like

You can convert Value to string directly as it implements Display and hence has a Value::to_string method, so using serde_json::to_string can be avoided.

Using .to_string() directly doesn't work either.

let val: String = new_json.get("id").unwrap().to_string();
let id: i32 = val.trim().parse::<i32>().unwrap();

What is the content of the string? What is the value of val?

val contains only a Number as a String.

This is how the JSON key-value pair looks like.

"id":"4"

The content of val is the string "4" instead of 4, which means that you need to strip out the quotes.

let id: i32 = val.trim().replace('"', "").parse().unwrap();

Instead of using replace() I used .as_str() which I already tried before but with the proposal from @jofas converting Value directly into a string worked well.

I'm not sure if I understand what your final solution is, but I was thinking about something like this, maybe:

use serde_json::Value;

fn main() {
    let json = r#"{
        "id": "4"
    }"#;
    
    let v: serde_json::Value = serde_json::from_str(json).unwrap();
    
    let Value::String(id) = v.get("id").unwrap() else {
        unreachable!();
    };
    
    let id: i32 = id.trim().parse().unwrap();
    
    println!("{id:?}");
}

Playground.

2 Likes