json mod added

pull/6/head
prplV 2025-02-13 10:23:38 +03:00
parent 784a6f7517
commit 5dae0fe2a5
3 changed files with 202 additions and 0 deletions

176
crates/api-grub/src/json.rs Normal file
View File

@ -0,0 +1,176 @@
// use serde::{de::value, Serialize};
use serde_json::{json, Value};
use integr_structs::api::v3::{TestMetric, TestMetricOutput};
pub struct JsonParser;
impl JsonParser {
pub fn parse(targets: &Vec<TestMetric>, json: &str) -> Value {
let mut res_vec: Vec<TestMetricOutput> = 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(TestMetricOutput::new_with_slices(&target.id, &target.json_type, metric));
}
serde_json::to_value(res_vec).unwrap_or(Value::Null)
}
fn get_sum_of_metrics_in_array(target: &TestMetric, 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: &TestMetric, 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
}
}
// pub struct TestMetric {
// pub id : String,
// pub json_type : String,
// pub addr : String,
// }
// #[derive(Serialize)]
// struct TestMetricOutput {
// id : String,
// json_type : String,
// value : Value,
// }
// impl TestMetricOutput {
// fn new_with_slices(id : &str, json_type : &str, value : Value) -> Self {
// TestMetricOutput {
// id : id.to_string(),
// json_type : json_type.to_string(),
// value : value,
// }
// }
// }

View File

@ -1,6 +1,7 @@
mod config; mod config;
mod net; mod net;
mod logger; mod logger;
mod json;
use anyhow::Result; use anyhow::Result;
use integr_structs::api::ApiConfigV2; use integr_structs::api::ApiConfigV2;

View File

@ -145,3 +145,28 @@ impl ProcessedEndpoint {
Ok(to_string_pretty(&val)?) Ok(to_string_pretty(&val)?)
} }
} }
pub mod v3 {
pub use super::*;
pub struct TestMetric {
pub id : String,
pub json_type : String,
pub addr : String,
}
#[derive(Serialize)]
pub struct TestMetricOutput {
id : String,
json_type : String,
value : Value,
}
impl TestMetricOutput {
pub fn new_with_slices(id : &str, json_type : &str, value : Value) -> Self {
TestMetricOutput {
id : id.to_string(),
json_type : json_type.to_string(),
value : value,
}
}
}
}