1use crate::api::Number::{Decimal, Integer};
2use crate::api::{Number, Value};
3use crate::array::Array;
4use crate::object::Object;
5
6fn from_array(array: &[serde_json::Value]) -> Array {
8 Array::from_iter(array.iter().filter_map(from_value))
9}
10
11fn from_number(value: &serde_json::Number) -> Option<Number> {
13 value
14 .as_i128()
15 .map_or_else(|| value.as_f64().map(Decimal), |i| Some(Integer(i)))
16}
17
18fn from_object(object: &serde_json::Map<String, serde_json::Value>) -> Object {
20 Object::from_iter(
21 object
22 .into_iter()
23 .filter_map(|e| from_value(e.1).map(|v| (e.0.clone(), v))),
24 )
25}
26
27pub fn from_value(value: &serde_json::Value) -> Option<Value> {
57 match value {
58 serde_json::Value::Array(v) => Some(Value::Array(from_array(v))),
59 serde_json::Value::Bool(v) => Some(Value::Bool(*v)),
60 serde_json::Value::Null => Some(Value::Null),
61 serde_json::Value::Number(v) => from_number(v).map(Value::Number),
62 serde_json::Value::Object(v) => Some(Value::Object(from_object(v))),
63 serde_json::Value::String(v) => Some(Value::String(v.clone())),
64 }
65}
66
67fn to_array(array: &Array) -> Vec<serde_json::Value> {
69 Vec::from_iter(array.iter().filter_map(|v| to_value(&v)))
70}
71
72fn to_number(value: &Number) -> Option<serde_json::Number> {
74 match value {
75 Decimal(v) => serde_json::Number::from_f64(*v),
76 Integer(v) => serde_json::Number::from_i128(*v),
77 }
78}
79
80fn to_object(object: &Object) -> serde_json::Map<String, serde_json::Value> {
82 serde_json::Map::from_iter(
83 object
84 .iter()
85 .filter_map(|e| to_value(&e.1).map(|v| (e.0, v))),
86 )
87}
88
89pub fn to_value(value: &Value) -> Option<serde_json::Value> {
91 match value {
92 Value::Array(v) => Some(serde_json::Value::Array(to_array(v))),
93 Value::Bool(v) => Some(serde_json::Value::Bool(*v)),
94 Value::Null => Some(serde_json::Value::Null),
95 Value::Number(v) => to_number(v).map(serde_json::Value::Number),
96 Value::Object(v) => Some(serde_json::Value::Object(to_object(v))),
97 Value::String(v) => Some(serde_json::Value::String(v.clone())),
98 }
99}