use nanoid::nanoid;
use serde_json::Value;
use crate::{IntoSVal, SData, SField, SGraph, SNodeRef, SVal};
pub(crate) fn parse_object_value(graph: &mut SGraph, node: &SNodeRef, value: Value) {
match value {
Value::Object(map) => {
for (field, val) in map {
let jf = parse_field_value(graph, node, val, &field);
SData::insert_new(graph, node, Box::new(jf));
}
},
_ => {}
}
}
pub(crate) fn parse_field_value(graph: &mut SGraph, node: &SNodeRef, value: Value, field: &str) -> SField {
match value {
Value::Null |
Value::Number(_) |
Value::String(_) |
Value::Bool(_) => {
SField::new(field, SVal::from(&value))
},
Value::Array(vals) => {
let mut jf_arr = Vec::new();
parse_array_values(graph, node, vals, &mut jf_arr, field);
SField::new(field, SVal::Array(jf_arr))
}
Value::Object(_) => {
let child_node = graph.insert_node(field, Some(node));
parse_object_value(graph, &child_node, value);
SField::new(field, child_node)
},
}
}
pub(crate) fn parse_array_values(graph: &mut SGraph, node: &SNodeRef, vals: Vec<Value>, res: &mut Vec<SVal>, field: &str) {
for val in vals {
match val {
Value::Null |
Value::String(_) |
Value::Number(_) |
Value::Bool(_) => {
res.push(SVal::from(&val));
},
Value::Object(_) => {
let name = format!("_a_obj{}", nanoid!(7));
let child_node = graph.insert_node(&name, Some(node));
parse_object_value(graph, &child_node, val);
res.push(SVal::Object(child_node));
},
Value::Array(vals) => {
let mut second_vals = Vec::new();
parse_array_values(graph, node, vals, &mut second_vals, field);
res.push(SVal::Array(second_vals));
},
}
}
}
impl IntoSVal for &Value {
fn stof_value(&self) -> SVal {
match self {
Value::Array(vals) => {
let mut arr = Vec::new();
for val in vals {
arr.push(SVal::from(val));
}
SVal::Array(arr)
},
Value::Bool(val) => {
SVal::Bool(*val)
},
Value::String(val) => {
SVal::String(val.clone())
},
Value::Number(val) => {
if val.is_i64() {
return val.as_i64().unwrap().into();
} else if val.is_u64() {
return (val.as_u64().unwrap() as i64).into();
} else if val.is_f64() {
return val.as_f64().unwrap().into();
}
SVal::Null
},
_ => {
SVal::Null
}
}
}
}