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