mecha10_dev/services/topology/
mod.rs1mod 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#[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#[derive(Debug, Clone, Serialize, Deserialize)]
31pub struct RedisInfo {
32 pub url: String,
33 pub host: String,
34 pub port: u16,
35}
36
37#[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#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
50pub struct TopicRef {
51 pub path: String,
52 pub message_type: Option<String>,
53}
54
55#[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
64pub struct TopologyService {
66 project_root: PathBuf,
67}
68
69impl TopologyService {
70 pub fn new(project_root: PathBuf) -> Self {
72 Self { project_root }
73 }
74
75 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}