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)]
21pub struct Topology {
22 pub project_name: String,
23 pub redis: RedisInfo,
24 pub nodes: Vec<NodeTopology>,
25 pub topics: Vec<TopicTopology>,
26}
27
28#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct RedisInfo {
30 pub url: String,
31 pub host: String,
32 pub port: u16,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize)]
36pub struct NodeTopology {
37 pub name: String,
38 pub package: String,
39 pub enabled: bool,
40 pub description: Option<String>,
41 pub publishes: Vec<TopicRef>,
42 pub subscribes: Vec<TopicRef>,
43}
44
45#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
46pub struct TopicRef {
47 pub path: String,
48 pub message_type: Option<String>,
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize)]
52pub struct TopicTopology {
53 pub path: String,
54 pub message_type: Option<String>,
55 pub publishers: Vec<String>,
56 pub subscribers: Vec<String>,
57}
58
59pub struct TopologyService {
60 project_root: PathBuf,
61}
62
63impl TopologyService {
64 pub fn new(project_root: PathBuf) -> Self {
66 Self { project_root }
67 }
68
69 pub async fn analyze(&self) -> Result<Topology> {
71 let config_path = self.project_root.join(paths::PROJECT_CONFIG);
72 let config = ConfigService::load_from(&config_path).await?;
73
74 let redis = self.parse_redis_url(&config.environments.redis_url())?;
75
76 let nodes = self.analyze_nodes(&config).await?;
77
78 let topics = self.build_topic_view(&nodes);
79
80 Ok(Topology {
81 project_name: config.name,
82 redis,
83 nodes,
84 topics,
85 })
86 }
87}