use crate::ig::builder::{DocBuilder, ListBuilder, ObjectBuilder};
use crate::ig::docs::Doc;
use anyhow::Context;
use serde_json::{Map, Value};
pub fn object_to_doc(object: &Map<String, Value>) -> anyhow::Result<Doc> {
let doc_builder = DocBuilder::new();
let mut obj_builder = doc_builder.obj();
transform_object(object, &doc_builder, &mut obj_builder)?;
Ok(doc_builder.build_object(obj_builder))
}
pub fn list_to_doc(list: &[Value]) -> anyhow::Result<Doc> {
let doc_builder = DocBuilder::new();
let mut list_builder = doc_builder.list();
transform_list(list, &doc_builder, &mut list_builder)?;
Ok(doc_builder.build_list(list_builder))
}
fn transform_list(
list: &[Value],
doc_builder: &DocBuilder,
builder: &mut ListBuilder,
) -> anyhow::Result<()> {
for value in list.iter() {
match value {
Value::Bool(value) => builder.append_bool(*value),
Value::Number(value) => {
builder.append_int(value.as_i64().context("Failed to convert number to i64")?)
}
Value::String(value) => builder.append_string(value),
Value::Array(inner_list) => {
let mut list_builder = doc_builder.list();
transform_list(inner_list, doc_builder, &mut list_builder)?;
builder.append_list(list_builder);
}
Value::Object(value) => {
let mut obj_builder = doc_builder.obj();
transform_object(value, doc_builder, &mut obj_builder)?;
builder.append_object(obj_builder);
}
Value::Null => {}
}
}
Ok(())
}
fn transform_object(
hash: &Map<String, Value>,
doc_builder: &DocBuilder,
builder: &mut ObjectBuilder,
) -> anyhow::Result<()> {
for (key, value) in hash {
match value {
Value::Bool(value) => builder.put_bool(key, *value)?,
Value::Number(value) => builder.put_int(
key,
value.as_i64().context("Failed to convert number to i64")?,
)?,
Value::String(value) => builder.put_string(key, value)?,
Value::Array(inner_list) => {
let mut list_builder = doc_builder.list();
transform_list(inner_list, doc_builder, &mut list_builder)?;
builder.put_list(key, list_builder)?;
}
Value::Object(value) => {
let mut obj_builder = doc_builder.obj();
transform_object(value, doc_builder, &mut obj_builder)?;
builder.put_object(key, obj_builder)?;
}
Value::Null => {}
}
}
Ok(())
}