use crate::lib::{json, Value, Map};
fn item_to_string(v: &Value) -> String {
match v {
Value::Null => "null".into(),
Value::Bool(_)
| Value::String(_)
| Value::Number(_)
| Value::Object(_)
| Value::Array(_) => crate::to_string_x(v.clone()),
}
}
fn value_to_kv(v: &Value) -> Option<(String, Option<Value>)> {
match v {
Value::Null => None,
Value::Bool(_) => None,
Value::Number(_) => None,
Value::String(s) => {
let mut chars = s.chars();
if let Some(k) = chars.next() {
let k = k.to_string();
if let Some(v) = chars.next() {
return Some((k, Some(Value::String(v.to_string()))));
}
return Some((k, None));
}
None
}
Value::Array(vec) => {
if let Some(k) = vec.get(0) {
let k = item_to_string(k);
if let Some(v) = vec.get(1) {
return Some((k, Some(v.clone())));
}
return Some((k, None));
}
None
}
Value::Object(_) => None,
}
}
fn append_array_to_object(array: &Value, mut map: Map<String, Value>) -> Map<String, Value> {
if let Some((k, v)) = value_to_kv(array) {
if let Some(vv) = v {
map.insert(k, vv);
} else {
map.remove(&k);
}
}
map
}
fn arrays_to_object(vec: Vec<Value>) -> Value {
let mut map = Map::new();
for item in vec.iter() {
map = append_array_to_object(item, map);
}
Value::Object(map)
}
pub fn from_pairs(v: Value) -> Value {
match v {
Value::Null => json!({}),
Value::Bool(_) => json!({}),
Value::Number(_) => json!({}),
Value::String(_) => json!({}),
Value::Array(vec) => arrays_to_object(vec),
Value::Object(_) => json!({}),
}
}
#[macro_export]
macro_rules! from_pairs {
() => {
json!({})
};
($a:expr $(,)*) => {
$crate::from_pairs($a)
};
($a:expr, $($rest:tt)*) => {
$crate::from_pairs($a)
};
}