iceoryx2_cli/
output.rs

1// Copyright (c) 2024 Contributors to the Eclipse Foundation
2//
3// See the NOTICE file(s) distributed with this work for additional
4// information regarding copyright ownership.
5//
6// This program and the accompanying materials are made available under the
7// terms of the Apache Software License 2.0 which is available at
8// https://www.apache.org/licenses/LICENSE-2.0, or the MIT license
9// which is available at https://opensource.org/licenses/MIT.
10//
11// SPDX-License-Identifier: Apache-2.0 OR MIT
12
13use 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}