Skip to main content

mecha10_dev/services/topology/
mod.rs

1//! Topology service for analyzing project structure
2//!
3//! This service provides static analysis of project topology including:
4//! - Nodes and their enabled status
5//! - Pub/sub topics (publishers and subscribers)
6//! - Service ports (Redis, HTTP, database, etc.)
7
8mod nodes;
9mod ports;
10mod source_scan;
11mod topics;
12
13use anyhow::Result;
14use serde::{Deserialize, Serialize};
15use std::path::PathBuf;
16
17use crate::paths;
18use crate::services::ConfigService;
19
20/// Topology analysis result
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct Topology {
23    pub project_name: String,
24    pub redis: RedisInfo,
25    pub nodes: Vec<NodeTopology>,
26    pub topics: Vec<TopicTopology>,
27}
28
29/// Redis connection information
30#[derive(Debug, Clone, Serialize, Deserialize)]
31pub struct RedisInfo {
32    pub url: String,
33    pub host: String,
34    pub port: u16,
35}
36
37/// Node topology information
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct NodeTopology {
40    pub name: String,
41    pub package: String,
42    pub enabled: bool,
43    pub description: Option<String>,
44    pub publishes: Vec<TopicRef>,
45    pub subscribes: Vec<TopicRef>,
46}
47
48/// Topic reference with message type
49#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
50pub struct TopicRef {
51    pub path: String,
52    pub message_type: Option<String>,
53}
54
55/// Topic topology information (grouped by topic)
56#[derive(Debug, Clone, Serialize, Deserialize)]
57pub struct TopicTopology {
58    pub path: String,
59    pub message_type: Option<String>,
60    pub publishers: Vec<String>,
61    pub subscribers: Vec<String>,
62}
63
64/// Topology service for static analysis
65pub struct TopologyService {
66    project_root: PathBuf,
67}
68
69impl TopologyService {
70    /// Create a new topology service
71    pub fn new(project_root: PathBuf) -> Self {
72        Self { project_root }
73    }
74
75    /// Analyze project topology
76    pub async fn analyze(&self) -> Result<Topology> {
77        let config_path = self.project_root.join(paths::PROJECT_CONFIG);
78        let config = ConfigService::load_from(&config_path).await?;
79
80        let redis = self.parse_redis_url(&config.environments.redis_url())?;
81
82        let nodes = self.analyze_nodes(&config).await?;
83
84        let topics = self.build_topic_view(&nodes);
85
86        Ok(Topology {
87            project_name: config.name,
88            redis,
89            nodes,
90            topics,
91        })
92    }
93}