ronf 0.4.2

Configuration system with saving
Documentation
use crate::value::{Map, Table, Value};

pub(crate) fn deserialize(content: String) -> Result<Map<String, Value>, String> {
    let json_content: serde_json::Value =
        serde_json::from_str(&content).map_err(|e| format!("Failed to parse JSON: {}", e))?;
    let mut map = Map::new();
    if let Some(obj) = json_content.as_object() {
        for (key, value) in obj {
            map.insert(key.clone(), from_json_value(value));
        }
    }
    Ok(map)
}

fn from_json_value(value: &serde_json::Value) -> Value {
    match value {
        serde_json::Value::Null => Value::None,
        serde_json::Value::Bool(b) => Value::Bool(*b),
        serde_json::Value::Number(n) => {
            if let Some(i) = n.as_i64() {
                Value::Int(i)
            } else {
                Value::Float(n.as_f64().unwrap_or(0.0))
            }
        }
        serde_json::Value::String(s) => Value::String(s.clone()),
        serde_json::Value::Array(arr) => {
            let mut values = Vec::new();
            for item in arr {
                values.push(from_json_value(item));
            }
            Value::Array(values)
        }
        serde_json::Value::Object(obj) => {
            let mut table = Table::new();
            for (key, value) in obj {
                table.insert(key.clone(), from_json_value(value));
            }
            Value::Table(table)
        }
    }
}

pub(crate) fn serialize(value: Map<String, Value>) -> String {
    let json_value = to_json_value(value);
    serde_json::to_string(&json_value).unwrap()
}

fn to_json_value(value: Map<String, Value>) -> serde_json::Value {
    serde_json::Value::Object(
        value
            .into_iter()
            .map(|(k, v)| (k, to_json_value_single(v)))
            .collect(),
    )
}

fn to_json_value_single(value: Value) -> serde_json::Value {
    match value {
        Value::None => serde_json::Value::Null,
        Value::Bool(b) => serde_json::Value::Bool(b),
        Value::Int(i) => serde_json::Value::Number(serde_json::Number::from(i)),
        Value::Float(f) => serde_json::Value::Number(serde_json::Number::from_f64(f).unwrap()),
        Value::String(s) => serde_json::Value::String(s),
        Value::Array(arr) => {
            serde_json::Value::Array(arr.into_iter().map(to_json_value_single).collect())
        }
        Value::Table(table) => to_json_value(table),
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::value::Value;

    #[test]
    fn test_invalid() {
        let json_string = r#"{"key": "value""#;
        let result = deserialize(json_string.to_string());
        assert!(result.is_err());
    }

    #[test]
    fn test_non_object_json() {
        let test_cases = vec![
            "42",        // Number
            "true",      // Boolean
            "\"hello\"", // String
            "null",      // Null
            "[]",        // Array
        ];

        for case in test_cases {
            let parsed_map = deserialize(case.to_string()).unwrap();
            assert!(parsed_map.is_empty());
        }
    }

    #[test]
    fn test_deserialize() {
        let json_string = r#"{"key":"value"}"#;
        let parsed_map = deserialize(json_string.to_string()).unwrap();
        assert_eq!(
            parsed_map,
            Map::from_iter(vec![(
                "key".to_string(),
                Value::String("value".to_string())
            )])
        );
    }

    #[test]
    fn test_deserialize_array() {
        let json_string = r#"{"array":[1,"two"]}"#;
        let parsed_map = deserialize(json_string.to_string()).unwrap();
        assert_eq!(
            parsed_map,
            Map::from_iter(vec![(
                "array".to_string(),
                Value::Array(vec![Value::Int(1), Value::String("two".to_string())])
            )])
        );
    }

    #[test]
    fn test_serialize() {
        let mut map = Map::new();
        map.insert("key".to_string(), Value::String("value".to_string()));
        let json_string = serialize(map);
        assert_eq!(json_string, r#"{"key":"value"}"#);
    }

    #[test]
    fn test_serialize_array() {
        let mut map = Map::new();
        map.insert(
            "array".to_string(),
            Value::Array(vec![Value::Int(1), Value::String("two".to_string())]),
        );
        let json_string = serialize(map);
        assert_eq!(json_string, r#"{"array":[1,"two"]}"#);
    }

    mod from_json_value {
        use super::*;

        #[test]
        fn test_from_null() {
            let json_value = serde_json::Value::Null;
            let parsed_value = from_json_value(&json_value);
            assert_eq!(parsed_value, Value::None);
        }

        #[test]
        fn test_from_bool() {
            let json_value = serde_json::Value::Bool(true);
            let parsed_value = from_json_value(&json_value);
            assert_eq!(parsed_value, Value::Bool(true));
        }

        #[test]
        fn test_from_int() {
            let json_value = serde_json::Value::Number(serde_json::Number::from(42));
            let parsed_value = from_json_value(&json_value);
            assert_eq!(parsed_value, Value::Int(42));
        }

        #[test]
        fn test_from_float() {
            let json_value = serde_json::Value::Number(serde_json::Number::from_f64(3.1).unwrap());
            let parsed_value = from_json_value(&json_value);
            assert_eq!(parsed_value, Value::Float(3.1));
        }

        #[test]
        fn test_from_string() {
            let json_value = serde_json::Value::String("Hello".to_string());
            let parsed_value = from_json_value(&json_value);
            assert_eq!(parsed_value, Value::String("Hello".to_string()));
        }

        #[test]
        fn test_from_array() {
            let json_value = serde_json::Value::Array(vec![
                serde_json::Value::Number(serde_json::Number::from(1)),
                serde_json::Value::String("two".to_string()),
            ]);
            let parsed_value = from_json_value(&json_value);
            assert_eq!(
                parsed_value,
                Value::Array(vec![Value::Int(1), Value::String("two".to_string())])
            );
        }

        #[test]
        fn test_from_object() {
            let json_value = serde_json::Value::Object(
                [(
                    "key".to_string(),
                    serde_json::Value::String("value".to_string()),
                )]
                .iter()
                .cloned()
                .collect(),
            );
            let parsed_value = from_json_value(&json_value);
            assert_eq!(
                parsed_value,
                Value::Table(Table::from_iter(vec![(
                    "key".to_string(),
                    Value::String("value".to_string())
                )]))
            );
        }
    }

    mod to_json_value {
        use super::*;

        #[test]
        fn test_none_to_json_value_single() {
            let value = Value::None;
            let json_value = to_json_value_single(value);
            assert_eq!(json_value, serde_json::Value::Null);
        }

        #[test]
        fn test_bool_to_json_value_single() {
            let value = Value::Bool(true);
            let json_value = to_json_value_single(value);
            assert_eq!(json_value, serde_json::Value::Bool(true));
        }

        #[test]
        fn test_int_to_json_value_single() {
            let value = Value::Int(42);
            let json_value = to_json_value_single(value);
            assert_eq!(
                json_value,
                serde_json::Value::Number(serde_json::Number::from(42))
            );
        }

        #[test]
        fn test_float_to_json_value_single() {
            let value = Value::Float(3.1);
            let json_value = to_json_value_single(value);
            assert_eq!(
                json_value,
                serde_json::Value::Number(serde_json::Number::from_f64(3.1).unwrap())
            );
        }

        #[test]
        fn test_string_to_json_value_single() {
            let value = Value::String("Hello".to_string());
            let json_value = to_json_value_single(value);
            assert_eq!(json_value, serde_json::Value::String("Hello".to_string()));
        }

        #[test]
        fn test_array_to_json_value_single() {
            let value = Value::Array(vec![Value::Int(1), Value::String("two".to_string())]);
            let json_value = to_json_value_single(value);
            assert_eq!(
                json_value,
                serde_json::Value::Array(vec![
                    serde_json::Value::Number(serde_json::Number::from(1)),
                    serde_json::Value::String("two".to_string())
                ])
            );
        }

        #[test]
        fn test_table_to_json_value_single() {
            let mut table = Table::new();
            table.insert("key".to_string(), Value::String("value".to_string()));
            let value = Value::Table(table);
            let json_value = to_json_value_single(value);
            assert_eq!(
                json_value,
                serde_json::Value::Object(
                    [(
                        "key".to_string(),
                        serde_json::Value::String("value".to_string())
                    )]
                    .iter()
                    .cloned()
                    .collect()
                )
            );
        }

        #[test]
        fn test_to_json_value() {
            let mut map = Map::new();
            map.insert("key".to_string(), Value::String("value".to_string()));
            let json_value = to_json_value(map);
            assert_eq!(
                json_value,
                serde_json::Value::Object(
                    [(
                        "key".to_string(),
                        serde_json::Value::String("value".to_string())
                    )]
                    .iter()
                    .cloned()
                    .collect()
                )
            );
        }
    }
}