1use alloc::string::String;
13use alloc::vec::Vec;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21pub enum BasicPortKind {
22 Reader,
24 Writer,
26 Updater,
28 Getter,
30 Listener,
32 StateListener,
34}
35
36#[derive(Debug, Clone, PartialEq, Eq)]
38pub struct BasicPort {
39 pub name: String,
41 pub kind: BasicPortKind,
43 pub type_id: String,
45}
46
47#[derive(Debug, Clone, Copy, PartialEq, Eq)]
53pub enum ExtendedPortKind {
54 MultiTopicReader,
56 ContentFilteredReader,
58 QueryConditionReader,
60 WaitsetReader,
62}
63
64#[derive(Debug, Clone, PartialEq, Eq)]
66pub struct ExtendedPort {
67 pub name: String,
69 pub kind: ExtendedPortKind,
71 pub type_id: String,
73}
74
75#[derive(Debug, Clone, Copy, PartialEq, Eq)]
81pub enum ConnectorPattern {
82 Base,
84 StateTransfer,
86 EventTransfer,
88 Dlrl,
90}
91
92#[derive(Debug, Clone, PartialEq, Eq)]
94pub struct Connector {
95 pub name: String,
97 pub pattern: ConnectorPattern,
99 pub type_id: String,
101 pub domain_id: u32,
103 pub qos_profile: Option<String>,
105 pub basic_ports: Vec<BasicPort>,
107 pub extended_ports: Vec<ExtendedPort>,
109}
110
111impl Connector {
112 #[must_use]
114 pub fn new(
115 name: impl Into<String>,
116 pattern: ConnectorPattern,
117 type_id: impl Into<String>,
118 ) -> Self {
119 Self {
120 name: name.into(),
121 pattern,
122 type_id: type_id.into(),
123 domain_id: 0,
124 qos_profile: None,
125 basic_ports: Vec::new(),
126 extended_ports: Vec::new(),
127 }
128 }
129
130 pub fn with_qos_profile(mut self, profile: impl Into<String>) -> Self {
132 self.qos_profile = Some(profile.into());
133 self
134 }
135
136 #[must_use]
138 pub fn with_domain(mut self, domain_id: u32) -> Self {
139 self.domain_id = domain_id;
140 self
141 }
142
143 pub fn add_basic_port(&mut self, p: BasicPort) {
145 self.basic_ports.push(p);
146 }
147
148 pub fn add_extended_port(&mut self, p: ExtendedPort) {
150 self.extended_ports.push(p);
151 }
152
153 #[must_use]
155 pub fn port_count(&self) -> usize {
156 self.basic_ports.len() + self.extended_ports.len()
157 }
158}
159
160#[derive(Debug, Clone, Copy, PartialEq, Eq)]
166pub enum ConnectorThreadingPolicy {
167 ThreadPerConnector,
169 SharedThreadPool,
171 InvokeInline,
173}
174
175pub mod qos_profiles {
181 pub const STATE_TRANSFER_DEFAULT: &str = "DDS4CCM:StateTransfer:Default";
184
185 pub const EVENT_TRANSFER_DEFAULT: &str = "DDS4CCM:EventTransfer:Default";
188
189 pub const BASE_DEFAULT: &str = "DDS4CCM:Base:Default";
192
193 pub const DLRL_DEFAULT: &str = "DDS4CCM:DLRL:Default";
195}
196
197#[derive(Debug, Clone, Copy, PartialEq, Eq)]
203pub enum DlrlPortKind {
204 CacheOperation,
206 ObjectHome,
208}
209
210#[derive(Debug, Clone, PartialEq, Eq)]
212pub struct DlrlPort {
213 pub name: String,
215 pub kind: DlrlPortKind,
217 pub type_id: String,
219}
220
221#[derive(Debug, Clone, Copy, PartialEq, Eq)]
227pub enum IdlOutputForm {
228 Idl3Compatible,
230 Idl3Plus,
232}
233
234#[cfg(test)]
239#[allow(clippy::expect_used)]
240mod tests {
241 use super::*;
242
243 #[test]
244 fn basic_port_kinds_distinct() {
245 assert_ne!(BasicPortKind::Reader, BasicPortKind::Writer);
246 assert_ne!(BasicPortKind::Updater, BasicPortKind::Getter);
247 assert_ne!(BasicPortKind::Listener, BasicPortKind::StateListener);
248 }
249
250 #[test]
251 fn basic_port_construct() {
252 let p = BasicPort {
253 name: "sensor".into(),
254 kind: BasicPortKind::Reader,
255 type_id: "IDL:demo/Sensor:1.0".into(),
256 };
257 assert_eq!(p.name, "sensor");
258 }
259
260 #[test]
261 fn extended_port_kinds_distinct() {
262 assert_ne!(
263 ExtendedPortKind::MultiTopicReader,
264 ExtendedPortKind::ContentFilteredReader
265 );
266 }
267
268 #[test]
269 fn connector_construct_default_domain_zero() {
270 let c = Connector::new("c", ConnectorPattern::Base, "IDL:T:1.0");
271 assert_eq!(c.domain_id, 0);
272 assert!(c.qos_profile.is_none());
273 assert_eq!(c.port_count(), 0);
274 }
275
276 #[test]
277 fn connector_with_qos_profile() {
278 let c = Connector::new("c", ConnectorPattern::StateTransfer, "IDL:T:1.0")
279 .with_qos_profile(qos_profiles::STATE_TRANSFER_DEFAULT)
280 .with_domain(42);
281 assert_eq!(
282 c.qos_profile.as_deref(),
283 Some("DDS4CCM:StateTransfer:Default")
284 );
285 assert_eq!(c.domain_id, 42);
286 }
287
288 #[test]
289 fn connector_add_basic_port_increments_count() {
290 let mut c = Connector::new("c", ConnectorPattern::Base, "IDL:T:1.0");
291 c.add_basic_port(BasicPort {
292 name: "in".into(),
293 kind: BasicPortKind::Reader,
294 type_id: "IDL:T:1.0".into(),
295 });
296 assert_eq!(c.port_count(), 1);
297 }
298
299 #[test]
300 fn connector_add_extended_port_increments_count() {
301 let mut c = Connector::new("c", ConnectorPattern::Base, "IDL:T:1.0");
302 c.add_extended_port(ExtendedPort {
303 name: "filt".into(),
304 kind: ExtendedPortKind::ContentFilteredReader,
305 type_id: "IDL:T:1.0".into(),
306 });
307 assert_eq!(c.port_count(), 1);
308 }
309
310 #[test]
311 fn connector_pattern_distinct() {
312 assert_ne!(ConnectorPattern::Base, ConnectorPattern::StateTransfer);
313 assert_ne!(ConnectorPattern::EventTransfer, ConnectorPattern::Dlrl);
314 }
315
316 #[test]
317 fn threading_policy_distinct() {
318 assert_ne!(
319 ConnectorThreadingPolicy::ThreadPerConnector,
320 ConnectorThreadingPolicy::SharedThreadPool
321 );
322 assert_ne!(
323 ConnectorThreadingPolicy::SharedThreadPool,
324 ConnectorThreadingPolicy::InvokeInline
325 );
326 }
327
328 #[test]
329 fn qos_profile_constants_match_spec_namespace() {
330 assert!(qos_profiles::STATE_TRANSFER_DEFAULT.starts_with("DDS4CCM:"));
331 assert!(qos_profiles::EVENT_TRANSFER_DEFAULT.starts_with("DDS4CCM:"));
332 assert!(qos_profiles::BASE_DEFAULT.starts_with("DDS4CCM:"));
333 assert!(qos_profiles::DLRL_DEFAULT.starts_with("DDS4CCM:"));
334 }
335
336 #[test]
337 fn dlrl_port_kinds_distinct() {
338 assert_ne!(DlrlPortKind::CacheOperation, DlrlPortKind::ObjectHome);
339 }
340
341 #[test]
342 fn dlrl_port_construct() {
343 let p = DlrlPort {
344 name: "trader_cache".into(),
345 kind: DlrlPortKind::CacheOperation,
346 type_id: "IDL:demo/TraderCache:1.0".into(),
347 };
348 assert_eq!(p.name, "trader_cache");
349 }
350
351 #[test]
352 fn idl_output_form_distinct() {
353 assert_ne!(IdlOutputForm::Idl3Compatible, IdlOutputForm::Idl3Plus);
354 }
355}