use std::{fmt::Debug, sync::Arc};
use crate::{
dds::{
participant::{DomainParticipant, DomainParticipantWeak},
qos::{HasQoSPolicy, QosPolicies},
typedesc::TypeDesc,
},
discovery::sedp_messages::TopicBuiltinTopicData,
};
pub use crate::structure::topic_kind::TopicKind;
pub trait TopicDescription {
fn participant(&self) -> Option<DomainParticipant>;
fn get_type(&self) -> TypeDesc; fn name(&self) -> String;
}
#[derive(Debug, Clone)]
pub struct TopicData {
pub name: String,
pub type_name: String,
pub qos: QosPolicies,
}
impl From<&TopicBuiltinTopicData> for TopicData {
fn from(tbtd: &TopicBuiltinTopicData) -> Self {
TopicData {
name: tbtd.name.clone(),
type_name: tbtd.type_name.clone(),
qos: tbtd.qos(),
}
}
}
#[derive(Clone)]
pub struct Topic {
inner: Arc<InnerTopic>,
}
impl Topic {
pub(crate) fn new(
my_domain_participant: &DomainParticipantWeak,
my_name: String,
my_typedesc: TypeDesc,
my_qos_policies: &QosPolicies,
topic_kind: TopicKind,
) -> Self {
Self {
inner: Arc::new(InnerTopic::new(
my_domain_participant,
my_name,
my_typedesc,
my_qos_policies,
topic_kind,
)),
}
}
fn participant(&self) -> Option<DomainParticipant> {
self.inner.participant()
}
fn get_type(&self) -> TypeDesc {
self.inner.get_type()
}
fn name(&self) -> String {
self.inner.name()
}
pub fn kind(&self) -> TopicKind {
self.inner.kind()
}
}
impl PartialEq for Topic {
fn eq(&self, other: &Self) -> bool {
self.inner == other.inner
}
}
impl Debug for Topic {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.inner.fmt(f)
}
}
impl TopicDescription for Topic {
fn participant(&self) -> Option<DomainParticipant> {
self.participant()
}
fn get_type(&self) -> TypeDesc {
self.get_type()
}
fn name(&self) -> String {
self.name()
}
}
impl HasQoSPolicy for Topic {
fn qos(&self) -> QosPolicies {
self.inner.qos()
}
}
#[derive(Clone)]
pub struct InnerTopic {
my_domain_participant: DomainParticipantWeak,
my_name: String,
my_typedesc: TypeDesc,
my_qos_policies: QosPolicies,
topic_kind: TopicKind, }
impl InnerTopic {
fn new(
my_domain_participant: &DomainParticipantWeak,
my_name: String,
my_typedesc: TypeDesc,
my_qos_policies: &QosPolicies,
topic_kind: TopicKind,
) -> Self {
Self {
my_domain_participant: my_domain_participant.clone(),
my_name,
my_typedesc,
my_qos_policies: my_qos_policies.clone(),
topic_kind,
}
}
fn participant(&self) -> Option<DomainParticipant> {
self.my_domain_participant.clone().upgrade()
}
fn get_type(&self) -> TypeDesc {
self.my_typedesc.clone()
}
fn name(&self) -> String {
self.my_name.to_string()
}
pub fn kind(&self) -> TopicKind {
self.topic_kind
}
}
impl PartialEq for InnerTopic {
fn eq(&self, other: &Self) -> bool {
self.participant() == other.participant()
&& self.get_type() == other.get_type()
&& self.name() == other.name()
&& self.qos() == other.qos()
&& self.topic_kind == other.topic_kind
}
}
impl Debug for InnerTopic {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("{:?}", self.participant()))?;
f.write_fmt(format_args!("Topic name: {}", self.name()))?;
f.write_fmt(format_args!("Topic type: {:?}", self.get_type()))?;
f.write_fmt(format_args!("Topic QoS: {:?} ", self.qos()))
}
}
impl TopicDescription for InnerTopic {
fn participant(&self) -> Option<DomainParticipant> {
self.participant()
}
fn get_type(&self) -> TypeDesc {
self.get_type()
}
fn name(&self) -> String {
self.name()
}
}
impl HasQoSPolicy for InnerTopic {
fn qos(&self) -> QosPolicies {
self.my_qos_policies.clone()
}
}