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 services: Vec<ServiceInfo>,
26    pub nodes: Vec<NodeTopology>,
27    pub topics: Vec<TopicTopology>,
28}
29
30/// Redis connection information
31#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct RedisInfo {
33    pub url: String,
34    pub host: String,
35    pub port: u16,
36}
37
38/// Service port information
39#[derive(Debug, Clone, Serialize, Deserialize)]
40pub struct ServiceInfo {
41    pub name: String,
42    pub host: String,
43    pub port: u16,
44}
45
46/// Node topology information
47#[derive(Debug, Clone, Serialize, Deserialize)]
48pub struct NodeTopology {
49    pub name: String,
50    pub package: String,
51    pub enabled: bool,
52    pub description: Option<String>,
53    pub publishes: Vec<TopicRef>,
54    pub subscribes: Vec<TopicRef>,
55}
56
57/// Topic reference with message type
58#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
59pub struct TopicRef {
60    pub path: String,
61    pub message_type: Option<String>,
62}
63
64/// Topic topology information (grouped by topic)
65#[derive(Debug, Clone, Serialize, Deserialize)]
66pub struct TopicTopology {
67    pub path: String,
68    pub message_type: Option<String>,
69    pub publishers: Vec<String>,
70    pub subscribers: Vec<String>,
71}
72
73/// Topology service for static analysis
74pub struct TopologyService {
75    project_root: PathBuf,
76}
77
78impl TopologyService {
79    /// Create a new topology service
80    pub fn new(project_root: PathBuf) -> Self {
81        Self { project_root }
82    }
83
84    /// Analyze project topology
85    pub async fn analyze(&self) -> Result<Topology> {
86        // Load project configuration
87        let config_path = self.project_root.join(paths::PROJECT_CONFIG);
88        let config = ConfigService::load_from(&config_path).await?;
89
90        // Parse Redis URL (derived from environments config)
91        let redis = self.parse_redis_url(&config.environments.redis_url())?;
92
93        // Extract service ports
94        let services = self.extract_services(&config);
95
96        // Analyze all enabled nodes
97        let nodes = self.analyze_nodes(&config).await?;
98
99        // Build topic-centric view
100        let topics = self.build_topic_view(&nodes);
101
102        Ok(Topology {
103            project_name: config.name,
104            redis,
105            services,
106            nodes,
107            topics,
108        })
109    }
110}