use crate::FileUtil;
use serde_json::Value;
use std::io;
use std::path::Path;
#[derive(Debug)]
pub struct JsonWrapper {
pub raw_data: String,
pub data: Value,
}
pub struct ValueWrapper<'a> {
value: &'a Value,
}
impl<'a> ValueWrapper<'a> {
pub fn new(value: &'a Value) -> Self {
Self { value }
}
pub fn get(&self, key: &'a str) -> Vec<&'a Value> {
let mut results = Vec::new();
if let Some((left, right)) = key.split_once(".") {
let x = self.value.get(left);
if x.is_none() {
results.push(&Value::Null);
} else {
let x = x.unwrap();
let next = ValueWrapper::new(x);
results.append(&mut next.get(right));
}
} else {
match self.value {
Value::Object(map) => {
if let Some(v) = map.get(key) {
results.push(v);
} else {
results.push(&Value::Null);
}
}
Value::Array(vec) => {
for item in vec {
match item.get(key) {
Some(v) => results.push(v),
None => results.push(&Value::Null),
}
}
}
_ => results.push(&Value::Null),
}
}
results
}
}
impl JsonWrapper {
pub fn new(file_path: &str) -> io::Result<Self> {
let conf_string = FileUtil::read_string(Path::new(file_path))?;
let data: Value = serde_json::from_str(&conf_string)?;
Ok(Self {
raw_data: conf_string,
data,
})
}
pub fn from_string(conf_string: &str) -> io::Result<Self> {
let data: Value = serde_json::from_str(conf_string)?;
Ok(Self {
raw_data: conf_string.to_string(),
data,
})
}
pub fn get<'a, 'b: 'a>(&'a self, key: &'b str) -> Vec<&'a Value> {
let wrapper = ValueWrapper::new(&self.data);
wrapper.get(key)
}
pub fn get_one<'a, 'b: 'a>(&'a self, key: &'b str) -> &'a Value {
let wrapper = ValueWrapper::new(&self.data);
let vec = wrapper.get(key);
vec.first().unwrap()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_json_conf_util() {
let json_wrapper = JsonWrapper::new("docs/config.json").unwrap();
let x = json_wrapper.get("name");
println!("name = {:?}", x);
let x = json_wrapper.get("age");
println!("age = {:?}", x);
let x = json_wrapper.get("is_student");
println!("is_student = {:?}", x);
let x = json_wrapper.get("hobbies");
println!("hobbies = {:?}", x);
let x = json_wrapper.get("address");
println!("address = {:?}", x);
let x = json_wrapper.get("address.street");
println!("address.street = {:?}", x);
let x = json_wrapper.get("address.releases");
println!("address.releases = {:?}", x);
let x = json_wrapper.get("address.x.y");
println!("address.x.y = {:?}", x);
let x = json_wrapper.get("address.children.name");
println!("address.children.name = {:?}", x);
println!("=============================================================");
let name = json_wrapper.get_one("name").as_str().unwrap();
let age = json_wrapper.get_one("age").as_i64().unwrap();
println!("name = {:?}", name);
println!("age = {:?}", age);
let key = String::from("address.x.y");
let x = json_wrapper.get_one(&key).as_str().unwrap();
println!("address.x.y = {}", x);
}
}