fracturedjson 0.1.1

Rust port of FracturedJsonJs: human-friendly JSON formatter with optional comment support.
Documentation
use crate::error::FracturedJsonError;
use crate::model::{JsonItem, JsonItemType};

pub fn convert_value_to_dom(
    element: &serde_json::Value,
    prop_name: Option<&str>,
    recursion_limit: usize,
) -> Result<Option<JsonItem>, FracturedJsonError> {
    if recursion_limit == 0 {
        return Err(FracturedJsonError::simple(
            "Depth limit exceeded - possible circular reference",
        ));
    }

    let mut item = JsonItem::default();
    if let Some(name) = prop_name {
        item.name = serde_json::to_string(name).unwrap_or_else(|_| format!("\"{}\"", name));
    }

    match element {
        serde_json::Value::Null => {
            item.item_type = JsonItemType::Null;
            item.value = "null".to_string();
        }
        serde_json::Value::Bool(val) => {
            item.item_type = if *val {
                JsonItemType::True
            } else {
                JsonItemType::False
            };
            item.value = if *val {
                "true".to_string()
            } else {
                "false".to_string()
            };
        }
        serde_json::Value::Number(num) => {
            item.item_type = JsonItemType::Number;
            item.value = num.to_string();
        }
        serde_json::Value::String(val) => {
            item.item_type = JsonItemType::String;
            item.value = serde_json::to_string(val).unwrap_or_else(|_| format!("\"{}\"", val));
        }
        serde_json::Value::Array(arr) => {
            item.item_type = JsonItemType::Array;
            let mut children = Vec::with_capacity(arr.len());
            for child in arr {
                let converted = convert_value_to_dom(child, None, recursion_limit - 1)?;
                if let Some(child_item) = converted {
                    children.push(child_item);
                } else {
                    let null_item =
                        convert_value_to_dom(&serde_json::Value::Null, None, recursion_limit - 1)?;
                    if let Some(null_item) = null_item {
                        children.push(null_item);
                    }
                }
            }
            item.children = children;
        }
        serde_json::Value::Object(map) => {
            item.item_type = JsonItemType::Object;
            for (key, value) in map.iter() {
                let child = convert_value_to_dom(value, Some(key), recursion_limit - 1)?;
                if let Some(child_item) = child {
                    item.children.push(child_item);
                }
            }
        }
    }

    if !item.children.is_empty() {
        let highest_child_complexity = item
            .children
            .iter()
            .map(|ch| ch.complexity)
            .max()
            .unwrap_or(0);
        item.complexity = highest_child_complexity + 1;
    }

    Ok(Some(item))
}