datex_core/network/com_hub/
metadata.rs1use log::info;
2
3use crate::{
4 collections::HashMap,
5 network::{
6 com_hub::{
7 ComHub, managers::socket_manager::DynamicEndpointProperties,
8 },
9 com_interfaces::com_interface::ComInterfaceUUID,
10 },
11};
12
13use crate::{
14 network::com_interfaces::com_interface::properties::{
15 ComInterfaceProperties, InterfaceDirection,
16 },
17 values::core_values::endpoint::Endpoint,
18};
19
20use crate::{
21 network::com_hub::managers::com_interface_manager::InterfaceInfo,
22 prelude::*,
23};
24use core::fmt::Display;
25use itertools::Itertools;
26use serde::{Deserialize, Serialize};
27
28#[derive(Serialize, Deserialize, Debug)]
29#[cfg_attr(feature = "wasm_runtime", derive(tsify::Tsify))]
30pub struct ComHubMetadataInterfaceSocket {
31 pub uuid: String,
32 pub direction: InterfaceDirection,
33 pub endpoint: Option<Endpoint>,
34 pub properties: Option<DynamicEndpointProperties>,
35}
36
37#[derive(Serialize, Deserialize)]
38#[cfg_attr(feature = "wasm_runtime", derive(tsify::Tsify))]
39pub struct ComHubMetadataInterfaceSocketWithoutEndpoint {
40 pub uuid: String,
41 pub direction: InterfaceDirection,
42}
43
44#[derive(Serialize, Deserialize, Debug)]
45#[cfg_attr(feature = "wasm_runtime", derive(tsify::Tsify))]
46pub struct ComHubMetadataInterface {
47 pub uuid: String,
48 pub properties: ComInterfaceProperties,
49 pub sockets: Vec<ComHubMetadataInterfaceSocket>,
50 pub is_waiting_for_socket_connections: bool,
51}
52
53#[derive(Serialize, Deserialize, Debug)]
54#[cfg_attr(feature = "wasm_runtime", derive(tsify::Tsify))]
55pub struct ComHubMetadata {
56 pub endpoint: Endpoint,
57 pub interfaces: Vec<ComHubMetadataInterface>,
58}
59
60impl Display for ComHubMetadata {
61 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
62 writeln!(f, "ComHub ({})", self.endpoint)?;
63
64 for interface in &self.interfaces {
66 writeln!(
67 f,
68 " {}/{}{}{}:",
69 interface.properties.interface_type,
70 interface.properties.channel,
71 if interface.is_waiting_for_socket_connections {
72 " [accepting connections]"
73 } else {
74 ""
75 },
76 interface
77 .properties
78 .name
79 .clone()
80 .map(|n| format!(" ({n})"))
81 .unwrap_or("".to_string()),
82 )?;
83
84 let sorted_sockets = interface.sockets.iter().sorted_by_key(|s| {
86 match &s.properties {
87 Some(properties) => properties.distance,
88 None => i8::MAX,
89 }
90 });
91
92 for socket in sorted_sockets {
93 writeln!(
94 f,
95 " {} {}{} (distance: {}, uuid: {})",
96 match socket.direction {
97 InterfaceDirection::In => "──▶".to_string(),
98 InterfaceDirection::Out => "◀──".to_string(),
99 InterfaceDirection::InOut => "◀──▶".to_string(),
100 },
101 match &socket.properties {
102 Some(properties) => match properties.is_direct {
103 true => "".to_string(),
104 false => "[INDIRECT] ".to_string(),
105 },
106 None => "".to_string(),
107 },
108 match &socket.endpoint {
109 Some(endpoint) => endpoint.to_string(),
110 None => "unknown".to_string(),
111 },
112 match &socket.properties {
113 Some(properties) => properties.distance.to_string(),
114 None => "unknown".to_string(),
115 },
116 socket.uuid
117 )?;
118 }
119 }
120
121 Ok(())
122 }
123}
124
125impl ComHub {
126 pub fn get_metadata(&self) -> ComHubMetadata {
128 let mut metadata = ComHubMetadata {
129 endpoint: self.endpoint.clone(),
130 interfaces: Vec::new(),
131 };
132
133 let mut sockets_by_com_interface_uuid: HashMap<
134 ComInterfaceUUID,
135 Vec<ComHubMetadataInterfaceSocket>,
136 > = HashMap::new();
137
138 for (endpoint, sockets) in
139 self.socket_manager.endpoint_sockets.borrow().iter()
140 {
141 for (socket_uuid, properties) in sockets {
142 let socket = self
143 .socket_manager
144 .get_socket_by_uuid(socket_uuid)
145 .unwrap();
146 let com_interface_uuid = socket.interface_uuid.clone();
147 if !sockets_by_com_interface_uuid
148 .contains_key(&com_interface_uuid)
149 {
150 sockets_by_com_interface_uuid
151 .insert(com_interface_uuid.clone(), Vec::new());
152 }
153 sockets_by_com_interface_uuid
154 .get_mut(&com_interface_uuid)
155 .unwrap()
156 .push(ComHubMetadataInterfaceSocket {
157 uuid: socket_uuid.to_string(),
158 endpoint: Some(endpoint.clone()),
159 direction: socket.socket_properties.direction.clone(),
160 properties: Some(properties.clone()),
161 });
162 }
163 }
164
165 for (socket_uuid, socket) in self.socket_manager.sockets.borrow().iter()
166 {
167 if socket.endpoints.is_empty() {
169 let com_interface_uuid = socket.interface_uuid.clone();
170 if !sockets_by_com_interface_uuid
171 .contains_key(&com_interface_uuid)
172 {
173 sockets_by_com_interface_uuid
174 .insert(com_interface_uuid.clone(), Vec::new());
175 }
176 sockets_by_com_interface_uuid
177 .get_mut(&com_interface_uuid)
178 .unwrap()
179 .push(ComHubMetadataInterfaceSocket {
180 uuid: socket_uuid.to_string(),
181 direction: socket.socket_properties.direction.clone(),
182 endpoint: None,
183 properties: None,
184 });
185 continue;
186 }
187 }
188
189 for (
190 uuid,
191 InterfaceInfo {
192 properties,
193 is_waiting_for_socket_connections,
194 ..
195 },
196 ) in self.interfaces_manager.interfaces.borrow().iter()
197 {
198 metadata.interfaces.push(ComHubMetadataInterface {
199 uuid: uuid.to_string(),
200 properties: properties.as_ref().clone(),
201 sockets: sockets_by_com_interface_uuid
202 .remove(uuid)
203 .unwrap_or_default(),
204 is_waiting_for_socket_connections:
205 *is_waiting_for_socket_connections,
206 });
207 }
208
209 metadata
210 }
211
212 pub fn print_metadata(&self) {
214 let metadata = self.get_metadata();
215 info!("ComHub Metadata:\n{metadata}");
216 }
217}