154 lines
5.9 KiB
Rust
154 lines
5.9 KiB
Rust
// use serde::{de::value, Serialize};
|
|
use serde_json::{json, Value};
|
|
use integr_structs::api::v3::{Metric, MetricOutput};
|
|
|
|
pub struct JsonParser;
|
|
|
|
impl JsonParser {
|
|
pub fn parse(targets: &Vec<Metric>, json: &str) -> Value {
|
|
let mut res_vec: Vec<MetricOutput> = Vec::new();
|
|
for target in targets {
|
|
let metric = match target.addr.contains("[") {
|
|
true => JsonParser::get_sum_of_metrics_in_array(target, json),
|
|
false => JsonParser::get_metric(target, json),
|
|
};
|
|
res_vec.push(MetricOutput::new_with_slices(&target.id, &target.json_type, &target.addr, metric));
|
|
}
|
|
serde_json::to_value(res_vec).unwrap_or(Value::Null)
|
|
}
|
|
fn get_sum_of_metrics_in_array(target: &Metric, json: &str) -> Value {
|
|
if target.addr.is_empty() {
|
|
return Value::Null;
|
|
}
|
|
|
|
let mut vec_value: Vec<Value> = Vec::new();
|
|
let mut array_key = String::new();
|
|
let mut value_json: Value = serde_json::from_str(json).unwrap_or(Value::Null);
|
|
|
|
let target_attr_vec = target.addr
|
|
.split_terminator('.')
|
|
.collect::<Vec<&str>>();
|
|
// for keys in [] brackets
|
|
let mut key_tag = String::new();
|
|
|
|
for (global_idx, &key) in target_attr_vec.iter().enumerate() {
|
|
// if array
|
|
let key_checked = if key.contains('[') {
|
|
let key_idx = key.find("[").unwrap();
|
|
key_tag = key.chars()
|
|
.enumerate()
|
|
.filter(|(idx, chr)| *idx > key_idx && *chr != ']')
|
|
.map(|(_, chr)| chr)
|
|
.collect::<String>();
|
|
// dbg!(&key_tag);
|
|
key.chars()
|
|
.enumerate()
|
|
.filter(|(idx, _)| *idx < key_idx)
|
|
.map(|(_, chr)| chr)
|
|
.collect::<String>()
|
|
// dbg!(value_json.get(&array_key).unwrap_or(&Value::Null));
|
|
// value_json = value_json.get(array_key).unwrap_or(&Value::Null).clone();
|
|
// continue;
|
|
// new_key.as_str()
|
|
// dbg!(key); APPROVED
|
|
// TODO: need to check key in [] type of [KEY]
|
|
} else {key.to_owned()};
|
|
|
|
// if already array
|
|
match value_json.get(key_checked) {
|
|
Some(val) => {
|
|
match val {
|
|
Value::Array(array) => {
|
|
// form new target array
|
|
let new_array_target = target_attr_vec
|
|
.iter()
|
|
.enumerate()
|
|
.filter(|(idx, _)| *idx > global_idx)
|
|
.map(|(_, &chr)| chr.to_owned())
|
|
.collect::<Vec<String>>();
|
|
// get_values_in_array
|
|
// get_tags_in_array
|
|
// // slice_tags_with_values
|
|
// dbg!(&array);
|
|
// dbg!(&new_array_target);
|
|
let res_arr = Self::get_values_in_array(array, &new_array_target);
|
|
if &key_tag == "" {
|
|
return res_arr.into();
|
|
}
|
|
return Self::slice_with_tags_in_array(array, &res_arr, &key_tag).into()
|
|
|
|
},
|
|
_ => value_json = val.clone(),
|
|
}
|
|
},
|
|
None => return Value::Null,
|
|
}
|
|
}
|
|
value_json
|
|
}
|
|
|
|
fn slice_with_tags_in_array(array: &Vec<Value>, metrics: &Vec<Value>, tag_name: &str) -> Vec<Value> {
|
|
if tag_name.is_empty() {
|
|
return metrics.clone();
|
|
}
|
|
// array[0].as_object().unwrap_or(json!(Value::Null))
|
|
let mut values: Vec<Value> = Vec::new();
|
|
array.iter()
|
|
.enumerate()
|
|
.map(|(idx, val)| {
|
|
let val = val.get(tag_name).unwrap_or(&Value::Null).clone();
|
|
(serde_json::from_value::<serde_json::Map<String, Value>>(json!({tag_name: val})),
|
|
serde_json::from_value::<serde_json::Map<String, Value>>(metrics[idx].clone()))
|
|
})
|
|
.for_each(|(key, val)| {
|
|
// dbg!(&key);
|
|
if key.is_ok() && val.is_ok() {
|
|
let mut key = key.unwrap();
|
|
let mut val = val.unwrap();
|
|
key.append(&mut val);
|
|
values.push(json!(key));
|
|
}
|
|
});
|
|
if values.len() == 0 {
|
|
return metrics.clone();
|
|
}
|
|
values
|
|
}
|
|
fn get_values_in_array(array: &Vec<Value>, fields: &Vec<String>) -> Vec<Value> {
|
|
let mut values: Vec<Value> = Vec::new();
|
|
for obj in array {
|
|
// dbg!(obj);
|
|
let mut obrez = obj.clone();
|
|
for field in fields {
|
|
obrez = obrez.get(field).unwrap_or(&Value::Null).clone();
|
|
match obrez {
|
|
Value::Object(_) => {continue},
|
|
_ => {
|
|
values.push(json!({field: obrez.clone()}));
|
|
},
|
|
// None => {values.push(Value::Null)},
|
|
}
|
|
}
|
|
}
|
|
values
|
|
}
|
|
|
|
fn get_metric(target: &Metric, json: &str) -> Value {
|
|
if target.addr.is_empty() {
|
|
return Value::Null;
|
|
}
|
|
let mut value_json: Value = serde_json::from_str(json).unwrap_or(Value::Null);
|
|
|
|
let target_attr_vec = target.addr
|
|
.split_terminator('.')
|
|
.collect::<Vec<&str>>();
|
|
for key in target_attr_vec {
|
|
match value_json.get(key) {
|
|
Some(val) => value_json = val.clone(),
|
|
None => return Value::Null,
|
|
}
|
|
}
|
|
value_json
|
|
}
|
|
}
|