1use core::ops::Deref;
14
15use iceoryx2::node::NodeDetails as IceoryxNodeDetails;
16use iceoryx2::node::NodeId as IceoryxNodeId;
17use iceoryx2::node::NodeState as IceoryxNodeState;
18use iceoryx2::node::NodeView as IceoryxNodeView;
19use iceoryx2::service::attribute::AttributeSet as IceoryxAttributeSet;
20use iceoryx2::service::static_config::messaging_pattern::MessagingPattern as IceoryxMessagingPattern;
21use iceoryx2::service::Service as IceoryxService;
22use iceoryx2::service::ServiceDetails as IceoryxServiceDetails;
23use iceoryx2::service::ServiceDynamicDetails as IceoryxServiceDynamicDetails;
24use iceoryx2_pal_posix::posix::pid_t;
25
26#[derive(serde::Serialize, Debug, Eq, PartialEq, Ord, PartialOrd)]
27pub enum ServiceDescriptor {
28 PublishSubscribe(String),
29 Event(String),
30 RequestResponse(String),
31 Undefined(String),
32}
33
34impl<T> From<&IceoryxServiceDetails<T>> for ServiceDescriptor
35where
36 T: IceoryxService,
37{
38 fn from(service: &IceoryxServiceDetails<T>) -> Self {
39 match service.static_details.messaging_pattern() {
40 IceoryxMessagingPattern::PublishSubscribe(_) => {
41 ServiceDescriptor::PublishSubscribe(service.static_details.name().to_string())
42 }
43 IceoryxMessagingPattern::Event(_) => {
44 ServiceDescriptor::Event(service.static_details.name().to_string())
45 }
46 IceoryxMessagingPattern::RequestResponse(_) => {
47 ServiceDescriptor::RequestResponse(service.static_details.name().to_string())
48 }
49 _ => ServiceDescriptor::Undefined("Undefined".to_string()),
50 }
51 }
52}
53
54#[derive(serde::Serialize)]
55pub struct ServiceDescription {
56 pub service_id: String,
57 pub service_name: String,
58 pub attributes: IceoryxAttributeSet,
59 pub pattern: IceoryxMessagingPattern,
60 pub nodes: Option<NodeList>,
61}
62
63impl<T> From<&IceoryxServiceDetails<T>> for ServiceDescription
64where
65 T: IceoryxService,
66{
67 fn from(service: &IceoryxServiceDetails<T>) -> Self {
68 let config = &service.static_details;
69
70 ServiceDescription {
71 service_id: config.service_id().as_str().to_string(),
72 service_name: config.name().as_str().to_string(),
73 attributes: config.attributes().clone(),
74 pattern: config.messaging_pattern().clone(),
75 nodes: service.dynamic_details.as_ref().map(NodeList::from),
76 }
77 }
78}
79
80#[derive(serde::Serialize)]
81pub enum DiscoveryEvent<T> {
82 Added(T),
83 Removed(T),
84}
85
86#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize)]
87pub struct NodeIdString(String);
88
89impl From<&IceoryxNodeId> for NodeIdString {
90 fn from(id: &IceoryxNodeId) -> Self {
91 NodeIdString(format!("{:032x}", id.value()))
92 }
93}
94
95impl AsRef<str> for NodeIdString {
96 fn as_ref(&self) -> &str {
97 &self.0
98 }
99}
100
101impl Deref for NodeIdString {
102 type Target = str;
103
104 fn deref(&self) -> &Self::Target {
105 &self.0
106 }
107}
108
109impl PartialEq<str> for NodeIdString {
110 fn eq(&self, other: &str) -> bool {
111 self.0 == other
112 }
113}
114
115impl PartialEq<&str> for NodeIdString {
116 fn eq(&self, other: &&str) -> bool {
117 self.0 == *other
118 }
119}
120
121#[derive(serde::Serialize)]
122pub enum NodeState {
123 Alive,
124 Dead,
125 Inaccessible,
126 Undefined,
127}
128
129#[derive(serde::Serialize)]
130pub struct NodeDescriptor {
131 state: NodeState,
132 id: NodeIdString,
133 pid: pid_t,
134 executable: Option<String>,
135 name: Option<String>,
136}
137
138impl<T> From<&IceoryxNodeState<T>> for NodeDescriptor
139where
140 T: IceoryxService,
141{
142 fn from(node: &IceoryxNodeState<T>) -> Self {
143 match node {
144 IceoryxNodeState::Alive(view) => NodeDescriptor {
145 state: NodeState::Alive,
146 id: NodeIdString::from(view.id()),
147 pid: view.id().pid().value(),
148 executable: view
149 .details()
150 .as_ref()
151 .map(|details| details.executable().to_string()),
152 name: view
153 .details()
154 .as_ref()
155 .map(|details| details.name().as_str().to_string()),
156 },
157 IceoryxNodeState::Dead(view) => NodeDescriptor {
158 state: NodeState::Dead,
159 id: NodeIdString::from(view.id()),
160 pid: view.id().pid().value(),
161 executable: view
162 .details()
163 .as_ref()
164 .map(|details| details.executable().to_string()),
165 name: view
166 .details()
167 .as_ref()
168 .map(|details| details.name().as_str().to_string()),
169 },
170 IceoryxNodeState::Inaccessible(node_id) => NodeDescriptor {
171 state: NodeState::Inaccessible,
172 id: NodeIdString::from(node_id),
173 pid: node_id.pid().value(),
174 executable: None,
175 name: None,
176 },
177 IceoryxNodeState::Undefined(node_id) => NodeDescriptor {
178 state: NodeState::Undefined,
179 id: NodeIdString::from(node_id),
180 pid: node_id.pid().value(),
181 executable: None,
182 name: None,
183 },
184 }
185 }
186}
187
188#[derive(serde::Serialize)]
189pub struct NodeDescription {
190 state: NodeState,
191 id: NodeIdString,
192 pid: pid_t,
193 #[serde(flatten)]
194 details: Option<IceoryxNodeDetails>,
195}
196
197impl<T> From<&IceoryxNodeState<T>> for NodeDescription
198where
199 T: IceoryxService,
200{
201 fn from(node: &IceoryxNodeState<T>) -> Self {
202 match node {
203 IceoryxNodeState::Alive(view) => NodeDescription {
204 state: NodeState::Alive,
205 id: NodeIdString::from(view.id()),
206 pid: view.id().pid().value(),
207 details: view.details().clone(),
208 },
209 IceoryxNodeState::Dead(view) => NodeDescription {
210 state: NodeState::Dead,
211 id: NodeIdString::from(view.id()),
212 pid: view.id().pid().value(),
213 details: view.details().clone(),
214 },
215 IceoryxNodeState::Inaccessible(node_id) => NodeDescription {
216 state: NodeState::Inaccessible,
217 id: NodeIdString::from(node_id),
218 pid: node_id.pid().value(),
219 details: None,
220 },
221 IceoryxNodeState::Undefined(node_id) => NodeDescription {
222 state: NodeState::Undefined,
223 id: NodeIdString::from(node_id),
224 pid: node_id.pid().value(),
225 details: None,
226 },
227 }
228 }
229}
230
231#[derive(serde::Serialize)]
232pub struct NodeList {
233 pub num: usize,
234 pub details: Vec<NodeDescriptor>,
235}
236
237impl<T> From<&IceoryxServiceDynamicDetails<T>> for NodeList
238where
239 T: IceoryxService,
240{
241 fn from(details: &IceoryxServiceDynamicDetails<T>) -> Self {
242 NodeList {
243 num: details.nodes.len(),
244 details: details.nodes.iter().map(NodeDescriptor::from).collect(),
245 }
246 }
247}