use crate::api::Number::{Decimal, Integer};
use crate::api::{Number, Value};
use crate::array::Array;
use crate::object::Object;
fn from_array(array: &[serde_json::Value]) -> Array {
Array::from_iter(array.iter().filter_map(from_value))
}
fn from_number(value: &serde_json::Number) -> Option<Number> {
value
.as_i128()
.map_or_else(|| value.as_f64().map(Decimal), |i| Some(Integer(i)))
}
fn from_object(object: &serde_json::Map<String, serde_json::Value>) -> Object {
Object::from_iter(
object
.into_iter()
.filter_map(|(k, v)| from_value(v).map(|v| (k.clone(), v))),
)
}
pub fn from_value(value: &serde_json::Value) -> Option<Value> {
match value {
serde_json::Value::Array(v) => Some(Value::Array(from_array(v))),
serde_json::Value::Bool(v) => Some(Value::Bool(*v)),
serde_json::Value::Null => Some(Value::Null),
serde_json::Value::Number(v) => from_number(v).map(Value::Number),
serde_json::Value::Object(v) => Some(Value::Object(from_object(v))),
serde_json::Value::String(v) => Some(Value::String(v.clone())),
}
}
fn to_array(array: &Array) -> Vec<serde_json::Value> {
Vec::from_iter(array.iter().filter_map(|v| to_value(&v)))
}
fn to_number(value: &Number) -> Option<serde_json::Number> {
match value {
Decimal(v) => serde_json::Number::from_f64(*v),
Integer(v) => serde_json::Number::from_i128(*v),
}
}
fn to_object(object: &Object) -> serde_json::Map<String, serde_json::Value> {
serde_json::Map::from_iter(
object
.iter()
.filter_map(|(k, v)| to_value(&v).map(|v| (k, v))),
)
}
pub fn to_value(value: &Value) -> Option<serde_json::Value> {
match value {
Value::Array(v) => Some(serde_json::Value::Array(to_array(v))),
Value::Bool(v) => Some(serde_json::Value::Bool(*v)),
Value::Null => Some(serde_json::Value::Null),
Value::Number(v) => to_number(v).map(serde_json::Value::Number),
Value::Object(v) => Some(serde_json::Value::Object(to_object(v))),
Value::String(v) => Some(serde_json::Value::String(v.clone())),
}
}