use serde_json::Value;
const INDENT: &str = " ";
pub(super) fn json_lines(value: &Value) -> Vec<String> {
let mut lines = Vec::new();
push_members(value, "", &mut lines);
lines
}
pub(super) fn line_lines(line: &str) -> Vec<String> {
let hash = format!(
"chain_hash: {}",
kernel::ledger::chain_hash(line.as_bytes())
);
std::iter::once(hash)
.chain(json_lines(
&serde_json::from_str(line).unwrap_or_else(|_| Value::String(line.to_owned())),
))
.collect()
}
fn push_members(value: &Value, indent: &str, lines: &mut Vec<String>) {
match value {
Value::Object(members) => {
for (key, member) in members {
push_named(key, member, indent, lines);
}
}
Value::Array(items) => {
for (at, item) in items.iter().enumerate() {
push_named(&format!("[{at}]"), item, indent, lines);
}
}
Value::Null | Value::Bool(_) | Value::Number(_) | Value::String(_) => {
lines.push(format!("{indent}{value}"));
}
}
}
fn push_named(name: &str, value: &Value, indent: &str, lines: &mut Vec<String>) {
match value {
Value::Object(_) | Value::Array(_) => {
lines.push(format!("{indent}{name}:"));
push_members(value, &format!("{indent}{INDENT}"), lines);
}
Value::Null | Value::Bool(_) | Value::Number(_) | Value::String(_) => {
lines.push(format!("{indent}{name}: {value}"));
}
}
}