macro_rules! json_extract {
    ($keys:expr,$json:expr,$t:ty) => { ... };
}
Expand description

This macro reduces boilerplate when using serde_json::Value variants when trying to get into a nested property.

use std::fs;
// Include the crates  serde_json and serde
use serde_json;
use serde;
 
 
let json_parsed = serde_json::json!({
  "brand": {
    "tesla": {
        "model": {
            "designers": ["Mr Bean","Elon Mosk"]
           }
        }
    }
});
 
let mut a: Vec<String> = vec![];
let mut b: Vec<String>= vec![];
 
// Standard way
if let serde_json::Value::Object(brand) = &json_parsed {
    let brand = brand.get("brand").unwrap();
    if let serde_json::Value::Object(tesla) = &brand {
        let tesla = tesla.get("tesla").unwrap();
        if let serde_json::Value::Object(model) = &tesla {
            let model = model.get("model").unwrap();
            if let serde_json::Value::Object(designers) = &model {
                let res = designers.get("designers");
                a = serde_json::from_value::<Vec<String>>(res.unwrap().to_owned()).unwrap();
            }
        }
    }
}

// With the macro
b = json_extract::json_extract!("brand.tesla.model.designers", &json_parsed, Vec<String>).unwrap();


assert_eq!(a,b);

Macro args

The macro accepts 3 arguments:

  1. A &str containg the path, separated by “.”
  2. The serde_json::Value variable to read.
  3. The type of the property we want to get.

Types supported

json_serde::Value has the following variants:

  • Array
  • Bool
  • Null
  • Number
  • Object
  • String

The third parameter to pass in the macro is a Rust type, so, things we can pass if we want to get data from some variants:

Value variantRust types
ArrayVec<String>, Vec<bool>, Vec<f64>, Vec<Value>
Boolbool
Numberu32, i32, i64, f32, usize
ObjectValue
StringString
Nullnot supported