use crate::types::errors::Error;
use crate::types::models::IsotarpAnalysis;
use serde_json::{Map, Value};
use std::collections::BTreeMap;
use std::path::Path;
pub fn save_analysis(analysis: &IsotarpAnalysis, output_path: &Path) -> Result<(), Error> {
let mut value = serde_json::to_value(analysis)?;
if let Value::Object(map) = &mut value {
let sorted_value = sort_json_object(map);
let json = serde_json::to_string_pretty(&sorted_value)?;
std::fs::write(output_path, json)?;
return Ok(());
}
let json = serde_json::to_string_pretty(analysis)?;
std::fs::write(output_path, json)?;
Ok(())
}
fn sort_json_object(map: &Map<String, Value>) -> Value {
let mut sorted_map = BTreeMap::new();
for (key, value) in map {
let sorted_value = match value {
Value::Object(obj) => sort_json_object(obj),
Value::Array(arr) => {
let mut sorted_arr = Vec::new();
for item in arr {
match item {
Value::Object(obj) => sorted_arr.push(sort_json_object(obj)),
Value::Array(_) => sorted_arr.push(item.clone()), Value::Number(_) => {
let mut numbers: Vec<i64> =
arr.iter().filter_map(|v| v.as_i64()).collect();
numbers.sort();
return Value::Array(numbers.into_iter().map(Value::from).collect());
}
_ => sorted_arr.push(item.clone()),
}
}
Value::Array(sorted_arr)
}
_ => value.clone(),
};
sorted_map.insert(key.clone(), sorted_value);
}
serde_json::to_value(sorted_map).unwrap_or(Value::Object(map.clone()))
}