rustserde

Struct with dynamic fields


I have a code to convert json to struct using serde. But, got stuck at a json with dynamic keys.

The json will contain the price list. it can vary and will be dynamic

{"Price 1":{"price":9.99,"qty":1.0}, "Price 2":{"price":8.99,"qty":10.0}, "Price 3":{"price":7.99,"qty":20.0}}

or

{"Price 1":{"price":9.99,"qty":1.0}}

or

{}

This is my struct

#[derive(Clone, Debug, Deserialize, Serialize)]
struct Price {
    pub price: f64,
    pub qty: f64
}

Not getting how to serialize the prices to Vec<Price> using serde

serde_json::from_str(&price.value).unwrap()

Solution

  • You cannot do that with out-of-the-box serde, you will need to implement you own Deserialize trait for Price

    or the easier way:

    first parse it into HashMap<String,Price> then transform it into Vec<Price>

    use std::collections::HashMap;
    
    use serde::{Deserialize, Serialize};
    
    #[derive(Debug, Deserialize, Serialize)]
    pub struct Price {
        pub price: f64,
        pub qty: f64,
    }
    
    pub fn main() {
        let json = r#"
        {"Price 1":{"price":9.99,"qty":1.0}, "Price 2":{"price":8.99,"qty":10.0}, "Price 3":{"price":7.99,"qty":20.0}}
        "#;
    
        let prices: Vec<_> = serde_json::from_str::<HashMap<String, Price>>(json)
            .unwrap()
            .into_values()
            .collect();
    
        println!("{:?}", prices);
    }