use alloc::string::String;
use alloc::vec::Vec;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BasicPortKind {
Reader,
Writer,
Updater,
Getter,
Listener,
StateListener,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BasicPort {
pub name: String,
pub kind: BasicPortKind,
pub type_id: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ExtendedPortKind {
MultiTopicReader,
ContentFilteredReader,
QueryConditionReader,
WaitsetReader,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ExtendedPort {
pub name: String,
pub kind: ExtendedPortKind,
pub type_id: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ConnectorPattern {
Base,
StateTransfer,
EventTransfer,
Dlrl,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Connector {
pub name: String,
pub pattern: ConnectorPattern,
pub type_id: String,
pub domain_id: u32,
pub qos_profile: Option<String>,
pub basic_ports: Vec<BasicPort>,
pub extended_ports: Vec<ExtendedPort>,
}
impl Connector {
#[must_use]
pub fn new(
name: impl Into<String>,
pattern: ConnectorPattern,
type_id: impl Into<String>,
) -> Self {
Self {
name: name.into(),
pattern,
type_id: type_id.into(),
domain_id: 0,
qos_profile: None,
basic_ports: Vec::new(),
extended_ports: Vec::new(),
}
}
pub fn with_qos_profile(mut self, profile: impl Into<String>) -> Self {
self.qos_profile = Some(profile.into());
self
}
#[must_use]
pub fn with_domain(mut self, domain_id: u32) -> Self {
self.domain_id = domain_id;
self
}
pub fn add_basic_port(&mut self, p: BasicPort) {
self.basic_ports.push(p);
}
pub fn add_extended_port(&mut self, p: ExtendedPort) {
self.extended_ports.push(p);
}
#[must_use]
pub fn port_count(&self) -> usize {
self.basic_ports.len() + self.extended_ports.len()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ConnectorThreadingPolicy {
ThreadPerConnector,
SharedThreadPool,
InvokeInline,
}
pub mod qos_profiles {
pub const STATE_TRANSFER_DEFAULT: &str = "DDS4CCM:StateTransfer:Default";
pub const EVENT_TRANSFER_DEFAULT: &str = "DDS4CCM:EventTransfer:Default";
pub const BASE_DEFAULT: &str = "DDS4CCM:Base:Default";
pub const DLRL_DEFAULT: &str = "DDS4CCM:DLRL:Default";
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DlrlPortKind {
CacheOperation,
ObjectHome,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DlrlPort {
pub name: String,
pub kind: DlrlPortKind,
pub type_id: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum IdlOutputForm {
Idl3Compatible,
Idl3Plus,
}
#[cfg(test)]
#[allow(clippy::expect_used)]
mod tests {
use super::*;
#[test]
fn basic_port_kinds_distinct() {
assert_ne!(BasicPortKind::Reader, BasicPortKind::Writer);
assert_ne!(BasicPortKind::Updater, BasicPortKind::Getter);
assert_ne!(BasicPortKind::Listener, BasicPortKind::StateListener);
}
#[test]
fn basic_port_construct() {
let p = BasicPort {
name: "sensor".into(),
kind: BasicPortKind::Reader,
type_id: "IDL:demo/Sensor:1.0".into(),
};
assert_eq!(p.name, "sensor");
}
#[test]
fn extended_port_kinds_distinct() {
assert_ne!(
ExtendedPortKind::MultiTopicReader,
ExtendedPortKind::ContentFilteredReader
);
}
#[test]
fn connector_construct_default_domain_zero() {
let c = Connector::new("c", ConnectorPattern::Base, "IDL:T:1.0");
assert_eq!(c.domain_id, 0);
assert!(c.qos_profile.is_none());
assert_eq!(c.port_count(), 0);
}
#[test]
fn connector_with_qos_profile() {
let c = Connector::new("c", ConnectorPattern::StateTransfer, "IDL:T:1.0")
.with_qos_profile(qos_profiles::STATE_TRANSFER_DEFAULT)
.with_domain(42);
assert_eq!(
c.qos_profile.as_deref(),
Some("DDS4CCM:StateTransfer:Default")
);
assert_eq!(c.domain_id, 42);
}
#[test]
fn connector_add_basic_port_increments_count() {
let mut c = Connector::new("c", ConnectorPattern::Base, "IDL:T:1.0");
c.add_basic_port(BasicPort {
name: "in".into(),
kind: BasicPortKind::Reader,
type_id: "IDL:T:1.0".into(),
});
assert_eq!(c.port_count(), 1);
}
#[test]
fn connector_add_extended_port_increments_count() {
let mut c = Connector::new("c", ConnectorPattern::Base, "IDL:T:1.0");
c.add_extended_port(ExtendedPort {
name: "filt".into(),
kind: ExtendedPortKind::ContentFilteredReader,
type_id: "IDL:T:1.0".into(),
});
assert_eq!(c.port_count(), 1);
}
#[test]
fn connector_pattern_distinct() {
assert_ne!(ConnectorPattern::Base, ConnectorPattern::StateTransfer);
assert_ne!(ConnectorPattern::EventTransfer, ConnectorPattern::Dlrl);
}
#[test]
fn threading_policy_distinct() {
assert_ne!(
ConnectorThreadingPolicy::ThreadPerConnector,
ConnectorThreadingPolicy::SharedThreadPool
);
assert_ne!(
ConnectorThreadingPolicy::SharedThreadPool,
ConnectorThreadingPolicy::InvokeInline
);
}
#[test]
fn qos_profile_constants_match_spec_namespace() {
assert!(qos_profiles::STATE_TRANSFER_DEFAULT.starts_with("DDS4CCM:"));
assert!(qos_profiles::EVENT_TRANSFER_DEFAULT.starts_with("DDS4CCM:"));
assert!(qos_profiles::BASE_DEFAULT.starts_with("DDS4CCM:"));
assert!(qos_profiles::DLRL_DEFAULT.starts_with("DDS4CCM:"));
}
#[test]
fn dlrl_port_kinds_distinct() {
assert_ne!(DlrlPortKind::CacheOperation, DlrlPortKind::ObjectHome);
}
#[test]
fn dlrl_port_construct() {
let p = DlrlPort {
name: "trader_cache".into(),
kind: DlrlPortKind::CacheOperation,
type_id: "IDL:demo/TraderCache:1.0".into(),
};
assert_eq!(p.name, "trader_cache");
}
#[test]
fn idl_output_form_distinct() {
assert_ne!(IdlOutputForm::Idl3Compatible, IdlOutputForm::Idl3Plus);
}
}