use uuid::Uuid;
use crate::{GraphDBResult, GraphDBTrait};
pub async fn get_formatted_graph_data(
graph_db: &dyn GraphDBTrait,
dataset_id: Uuid,
user_id: Uuid,
) -> GraphDBResult<serde_json::Value> {
let _ = (dataset_id, user_id);
let (nodes, edges) = graph_db.get_graph_data().await?;
let node_values: Vec<serde_json::Value> = nodes
.into_iter()
.map(|(node_id, props)| format_node(&node_id, &props))
.collect();
let edge_values: Vec<serde_json::Value> = edges
.into_iter()
.map(|(source, target, relationship_name, _props)| {
serde_json::json!({
"source": source,
"target": target,
"label": relationship_name,
})
})
.collect();
Ok(serde_json::json!({
"nodes": node_values,
"edges": edge_values,
}))
}
fn format_node(node_id: &str, props: &crate::NodeData) -> serde_json::Value {
let type_str = props
.get("type")
.and_then(|v| v.as_str())
.unwrap_or("")
.to_string();
let name = props.get("name").and_then(|v| v.as_str()).unwrap_or("");
let label = if !name.is_empty() {
name.to_string()
} else {
format!("{type_str}_{node_id}")
};
let mut properties_map = serde_json::Map::new();
for (key, value) in props.iter() {
let k = key.as_ref();
if matches!(k, "id" | "type" | "name" | "created_at" | "updated_at") {
continue;
}
if value.is_null() {
continue;
}
properties_map.insert(k.to_string(), value.clone());
}
serde_json::json!({
"id": node_id,
"label": label,
"type": type_str,
"properties": serde_json::Value::Object(properties_map),
})
}