immutable_json/
serde.rs

1use crate::api::Number::{Decimal, Integer};
2use crate::api::{Number, Value};
3use crate::array::Array;
4use crate::object::Object;
5
6/// Convert a serde_json array to an immutable JSON array.
7fn from_array(array: &[serde_json::Value]) -> Array {
8    Array::from_iter(array.iter().filter_map(from_value))
9}
10
11/// Convert a serde_json number to an immutable JSON number.
12fn 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
18/// Convert a serde_json object to an immutable JSON object.
19fn 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
27/// Convert a serde_json value to an immutable JSON value.
28/// ```rust
29/// # use serde_json::Value;
30/// # use immutable_json::serde::{from_value, to_value};
31/// # use serde_json::Error;
32/// # fn main() -> Result<(), Error>{
33/// let data = r#"
34///         {
35///             "string": "string",
36///             "int": 43,
37///             "float": 5.8,
38///             "boolean": true,
39///             "object": {"test": "test"},
40///             "array": [
41///                 "string",
42///                 1,
43///                 3.0,
44///                 false,
45///                 {"test": "test"},
46///                 [1]
47///             ]
48///         }"#;
49///
50///     let v: Value = serde_json::from_str(data)?;
51///
52///     assert_eq!(Some(v.clone()), from_value(&v).and_then(|f| to_value(&f)));
53/// #   Ok(())
54/// # }
55/// ```
56pub 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
67/// Convert an immutable JSON array to a serde_json array.
68fn to_array(array: &Array) -> Vec<serde_json::Value> {
69    Vec::from_iter(array.iter().filter_map(|v| to_value(&v)))
70}
71
72/// Convert an immutable JSON number to a serde_json number.
73fn 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
80/// Convert an immutable JSON object to a serde_json object.
81fn 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
89/// Convert an immutable JSON value to a serde_json value.
90pub 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}