object-space 0.1.1

An object store library for highly concurrent program written in Rust.
Documentation
use std::iter::Peekable;

use serde_json::map::Map;
use serde_json::value::Value;

pub fn flatten(v: Value) -> Value {
    match v {
        Value::Object(_) => {
            let mut result = Map::new();
            flatten_helper("", v, &mut result);
            Value::Object(result)
        }
        _ => v,
    }
}

pub fn deflatten(v: Value) -> Value {
    match v {
        Value::Object(map) => Value::Object(deflatten_helper(map)),
        _ => v,
    }
}

fn flatten_helper(path: &str, value: Value, result: &mut Map<String, Value>) {
    match value {
        Value::Object(map) => for (k, v) in map {
            let new_path = if path.is_empty() {
                k
            } else {
                format!("{}.{}", path, k)
            };
            flatten_helper(&new_path, v, result)
        },
        _ => {
            result.insert(path.to_owned(), value);
        }
    }
}

fn deflatten_helper(map: Map<String, Value>) -> Map<String, Value> {
    let mut result = Map::new();
    for (key, value) in map {
        insert_to_map(&mut result, &mut key.split('.').peekable(), value);
    }
    result
}

fn insert_to_map<'a, I>(map: &mut Map<String, Value>, iter: &mut Peekable<I>, value: Value)
where
    I: Iterator<Item = &'a str>,
{
    if let Some(field_val) = iter.next() {
        match iter.peek() {
            Some(_) => {
                let child = map.entry(field_val).or_insert(Value::Object(Map::new()));
                insert_to_map(child.as_object_mut().expect("invalid JSON"), iter, value);
            }
            None => {
                map.insert(field_val.to_owned(), value);
            }
        }
    }
}