3

I have some json with from an external API that I would like to type. The shape of the data looks like:

{
 "summary": {
    "field1": "foo",
    "field2": "bar",
  },
 "0": {
   "fieldA": "123",
   "fieldB": "foobar"
 },
 "1": {
   "fieldA": "245",
   "fieldB": "foobar"
 },
 ...
}

There is an unknown number of indexed objects returned below the summary field, depending on the query that is run. These objects have the same shape, but a different shape than the "summary" object. I would like to use serde_json to type this response into something like:

#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SearchResults {
    pub summary: Summary,
    pub results: Vec<IndexedFieldType>
}

Is it possible to do this with serde macros? Is there a "all other fields" catchall that I can flatten into a vec?

wileybaba
  • 380
  • 1
  • 3
  • 11

1 Answers1

2

I ended up doing this manually like so:

let summary = &json.search_results["summary"];
let summary: Summary = serde_json::from_value(summary.to_owned()).unwrap();
let results: Vec<SearchResult> = json
        .search_results
        .as_object()
        .unwrap()
        .iter()
        .filter(|(key, _val)| key.parse::<i32>().is_ok())
        .map(|(_key, value)| serde_json::from_value(value.to_owned()).unwrap())
        .collect();
        
Ok(SearchResults {
            summary,
            results
        })
wileybaba
  • 380
  • 1
  • 3
  • 11