0

I'm building a React app utilizing Rust for complex computations. In this case I'm passing a JSON formatted string from the React app to Rust:

{
  {'clientid': 1, 'category': 'Category #1', 'subcategory': 'Subcategory #1', 'cost': 1000.00},
  {'clientid': 1, 'category': 'Category #1', 'subcategory': 'Subcategory #2', 'cost': 2000.00}
}

I'm trying to figure out how to deserialze string In Rust into an array of structs defined as:

#[derive(Serialize, Deserialize, Debug)]
struct ClientBudget {
    clientid: u32,
    category: String,
    subcategory: String,
    cost: f32,
}

I tried:

let deserialized: ClientBudget = serde_json::from_str(&some_json).unwrap();

But this causes a panic:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("key must be a string"

How do I get Rust/serde to process this JSON string?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
chasahodge
  • 373
  • 1
  • 4
  • 11
  • 2
    If the string you are passing is exactly like you have shown at the top of your question, the error is because it is not valid JSON (uses `'` instead of `"` and isn't using `[]` for the array). In the future, please include a [mcve] in your question that demonstrates the problem, and preferably a [Rust playground](https://play.rust-lang.org/) link. – Herohtar Aug 19 '20 at 17:40
  • There are many online tools you can use to validate your JSON string. https://jsonlint.com/ is the first I found on a quick search. You can also use `JSON.parse()` in your browsers JSON console. – Shepmaster Aug 19 '20 at 17:51
  • Please don't change your question after receiving an answer. You are encouraged to instead open a new question (looking for any duplicates before asking it). – Shepmaster Aug 19 '20 at 19:48
  • See also [How to set input as raw string in Rust?](https://stackoverflow.com/q/37889091/155423) – Shepmaster Aug 19 '20 at 19:48
  • apologies, I thought that was what I was supposed to do after reading the info on the closed status. Thanks for your help. – chasahodge Aug 19 '20 at 19:51

1 Answers1

0

Your JSON is badly formatted. If you want a list, you must use [] not {}. You also need to deserialize a Vec of objects:

use serde::{Deserialize, Serialize}; // 1.0.114

#[derive(Serialize, Deserialize, Debug)]
struct ClientBudget {
    clientid: u32,
    category: String,
    subcategory: String,
    cost: f32,
}

fn main() {
    let data = r#"
[
    {"clientid": 1, "category": "Category #1", "subcategory": "Subcategory #1", "cost": 1000.00},
    {"clientid": 1, "category": "Category #1", "subcategory": "Subcategory #2", "cost": 2000.00}
]
    "#;
    let deserialized: Vec<ClientBudget> = serde_json::from_str(data).unwrap();

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

Playground

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Netwave
  • 40,134
  • 6
  • 50
  • 93
  • 1
    Your example/solution shows a Rust Vec object. That’s not what is being passed to Rust from React. What I’m getting from React is the form shown in my example which is proper JSON. – chasahodge Aug 19 '20 at 17:48
  • *which is proper JSON* — [citation needed]. – Shepmaster Aug 19 '20 at 17:51
  • 5
    My apologies. I was incorrect. I have always used the format shown in my example for JSON formatted data. Upon examining my output from react and using an online JSON validator I see now that I am wrong. Don’t know when things changed or how I got away with that structure in the past, but I now see the error of my ways. Thanks and apologies. – chasahodge Aug 19 '20 at 18:10