mod nodes;
mod ports;
mod source_scan;
mod topics;
use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use crate::paths;
use crate::services::ConfigService;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Topology {
pub project_name: String,
pub redis: RedisInfo,
pub nodes: Vec<NodeTopology>,
pub topics: Vec<TopicTopology>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RedisInfo {
pub url: String,
pub host: String,
pub port: u16,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NodeTopology {
pub name: String,
pub package: String,
pub enabled: bool,
pub description: Option<String>,
pub publishes: Vec<TopicRef>,
pub subscribes: Vec<TopicRef>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub struct TopicRef {
pub path: String,
pub message_type: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TopicTopology {
pub path: String,
pub message_type: Option<String>,
pub publishers: Vec<String>,
pub subscribers: Vec<String>,
}
pub struct TopologyService {
project_root: PathBuf,
}
impl TopologyService {
pub fn new(project_root: PathBuf) -> Self {
Self { project_root }
}
pub async fn analyze(&self) -> Result<Topology> {
let config_path = self.project_root.join(paths::PROJECT_CONFIG);
let config = ConfigService::load_from(&config_path).await?;
let redis = self.parse_redis_url(&config.environments.redis_url())?;
let nodes = self.analyze_nodes(&config).await?;
let topics = self.build_topic_view(&nodes);
Ok(Topology {
project_name: config.name,
redis,
nodes,
topics,
})
}
}