use crate::{
dcps::infrastructure::error::{DdsError, DdsResult},
infrastructure::time::Duration,
};
use super::{
qos_policy::{
DataRepresentationQosPolicy, DeadlineQosPolicy, DestinationOrderQosPolicy,
DurabilityQosPolicy, EntityFactoryQosPolicy, GroupDataQosPolicy, HistoryQosPolicy,
HistoryQosPolicyKind, LatencyBudgetQosPolicy, LifespanQosPolicy, LivelinessQosPolicy,
OwnershipQosPolicy, OwnershipStrengthQosPolicy, PartitionQosPolicy, PresentationQosPolicy,
ReaderDataLifecycleQosPolicy, ReliabilityQosPolicy, ReliabilityQosPolicyKind,
ResourceLimitsQosPolicy, TimeBasedFilterQosPolicy, TopicDataQosPolicy,
TransportPriorityQosPolicy, UserDataQosPolicy, WriterDataLifecycleQosPolicy,
},
time::DurationKind,
};
#[derive(Debug, Default, PartialEq, Eq, Clone)]
pub struct DomainParticipantFactoryQos {
pub entity_factory: EntityFactoryQosPolicy,
}
#[derive(Debug)]
pub enum QosKind<T> {
Default,
Specific(T),
}
#[derive(Debug, Default, PartialEq, Eq, Clone)]
pub struct DomainParticipantQos {
pub user_data: UserDataQosPolicy,
pub entity_factory: EntityFactoryQosPolicy,
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct PublisherQos {
pub presentation: PresentationQosPolicy,
pub partition: PartitionQosPolicy,
pub group_data: GroupDataQosPolicy,
pub entity_factory: EntityFactoryQosPolicy,
}
impl PublisherQos {
pub const fn const_default() -> Self {
Self {
presentation: PresentationQosPolicy::const_default(),
partition: PartitionQosPolicy::const_default(),
group_data: GroupDataQosPolicy::const_default(),
entity_factory: EntityFactoryQosPolicy::const_default(),
}
}
}
impl Default for PublisherQos {
fn default() -> Self {
Self::const_default()
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct DataWriterQos {
pub durability: DurabilityQosPolicy,
pub deadline: DeadlineQosPolicy,
pub latency_budget: LatencyBudgetQosPolicy,
pub liveliness: LivelinessQosPolicy,
pub reliability: ReliabilityQosPolicy,
pub destination_order: DestinationOrderQosPolicy,
pub history: HistoryQosPolicy,
pub resource_limits: ResourceLimitsQosPolicy,
pub transport_priority: TransportPriorityQosPolicy,
pub lifespan: LifespanQosPolicy,
pub user_data: UserDataQosPolicy,
pub ownership: OwnershipQosPolicy,
pub ownership_strength: OwnershipStrengthQosPolicy,
pub writer_data_lifecycle: WriterDataLifecycleQosPolicy,
pub representation: DataRepresentationQosPolicy,
}
impl DataWriterQos {
pub const fn const_default() -> Self {
Self {
reliability: ReliabilityQosPolicy {
kind: ReliabilityQosPolicyKind::Reliable,
max_blocking_time: DurationKind::Finite(Duration::new(
0,
100_000_000,
)),
},
durability: DurabilityQosPolicy::const_default(),
deadline: DeadlineQosPolicy::const_default(),
latency_budget: LatencyBudgetQosPolicy::const_default(),
liveliness: LivelinessQosPolicy::const_default(),
destination_order: DestinationOrderQosPolicy::const_default(),
history: HistoryQosPolicy::const_default(),
resource_limits: ResourceLimitsQosPolicy::const_default(),
user_data: UserDataQosPolicy::const_default(),
ownership: OwnershipQosPolicy::const_default(),
ownership_strength: OwnershipStrengthQosPolicy::const_default(),
lifespan: LifespanQosPolicy::const_default(),
transport_priority: TransportPriorityQosPolicy::const_default(),
writer_data_lifecycle: WriterDataLifecycleQosPolicy::const_default(),
representation: DataRepresentationQosPolicy::const_default(),
}
}
}
impl Default for DataWriterQos {
fn default() -> Self {
Self::const_default()
}
}
impl DataWriterQos {
pub(crate) fn is_consistent(&self) -> DdsResult<()> {
if self.representation.value.len() > 1 {
return Err(DdsError::InconsistentPolicy);
}
if self.resource_limits.max_samples < self.resource_limits.max_samples_per_instance {
return Err(DdsError::InconsistentPolicy);
}
match self.history.kind {
HistoryQosPolicyKind::KeepLast(depth) => {
if depth as usize > self.resource_limits.max_samples_per_instance {
Err(DdsError::InconsistentPolicy)
} else {
Ok(())
}
}
HistoryQosPolicyKind::KeepAll => Ok(()),
}
}
pub(crate) fn check_immutability(&self, other: &Self) -> DdsResult<()> {
if self.durability != other.durability
|| self.liveliness != other.liveliness
|| self.reliability != other.reliability
|| self.destination_order != other.destination_order
|| self.history != other.history
|| self.resource_limits != other.resource_limits
|| self.ownership != other.ownership
{
Err(DdsError::ImmutablePolicy)
} else {
Ok(())
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct SubscriberQos {
pub presentation: PresentationQosPolicy,
pub partition: PartitionQosPolicy,
pub group_data: GroupDataQosPolicy,
pub entity_factory: EntityFactoryQosPolicy,
}
impl SubscriberQos {
pub const fn const_default() -> Self {
Self {
presentation: PresentationQosPolicy::const_default(),
partition: PartitionQosPolicy::const_default(),
group_data: GroupDataQosPolicy::const_default(),
entity_factory: EntityFactoryQosPolicy::const_default(),
}
}
pub(crate) fn check_immutability(&self, other: &Self) -> DdsResult<()> {
if self.presentation != other.presentation {
Err(DdsError::ImmutablePolicy)
} else {
Ok(())
}
}
}
impl Default for SubscriberQos {
fn default() -> Self {
Self::const_default()
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct DataReaderQos {
pub durability: DurabilityQosPolicy,
pub deadline: DeadlineQosPolicy,
pub latency_budget: LatencyBudgetQosPolicy,
pub liveliness: LivelinessQosPolicy,
pub reliability: ReliabilityQosPolicy,
pub destination_order: DestinationOrderQosPolicy,
pub history: HistoryQosPolicy,
pub resource_limits: ResourceLimitsQosPolicy,
pub user_data: UserDataQosPolicy,
pub ownership: OwnershipQosPolicy,
pub time_based_filter: TimeBasedFilterQosPolicy,
pub reader_data_lifecycle: ReaderDataLifecycleQosPolicy,
pub representation: DataRepresentationQosPolicy,
}
impl DataReaderQos {
pub const fn const_default() -> Self {
Self {
reliability: ReliabilityQosPolicy {
kind: ReliabilityQosPolicyKind::BestEffort,
max_blocking_time: DurationKind::Finite(Duration::new(
0,
100_000_000,
)),
},
durability: DurabilityQosPolicy::const_default(),
deadline: DeadlineQosPolicy::const_default(),
latency_budget: LatencyBudgetQosPolicy::const_default(),
liveliness: LivelinessQosPolicy::const_default(),
destination_order: DestinationOrderQosPolicy::const_default(),
history: HistoryQosPolicy::const_default(),
resource_limits: ResourceLimitsQosPolicy::const_default(),
user_data: UserDataQosPolicy::const_default(),
ownership: OwnershipQosPolicy::const_default(),
time_based_filter: TimeBasedFilterQosPolicy::const_default(),
reader_data_lifecycle: ReaderDataLifecycleQosPolicy::const_default(),
representation: DataRepresentationQosPolicy::const_default(),
}
}
}
impl Default for DataReaderQos {
fn default() -> Self {
Self::const_default()
}
}
impl DataReaderQos {
pub(crate) fn is_consistent(&self) -> DdsResult<()> {
if self.resource_limits.max_samples < self.resource_limits.max_samples_per_instance {
return Err(DdsError::InconsistentPolicy);
}
match self.history.kind {
HistoryQosPolicyKind::KeepLast(depth) => {
if depth as usize > self.resource_limits.max_samples_per_instance {
return Err(DdsError::InconsistentPolicy);
}
}
HistoryQosPolicyKind::KeepAll => (),
}
if self.deadline.period < self.time_based_filter.minimum_separation {
return Err(DdsError::InconsistentPolicy);
}
Ok(())
}
pub(crate) fn check_immutability(&self, other: &Self) -> DdsResult<()> {
if self.durability != other.durability
|| self.liveliness != other.liveliness
|| self.reliability != other.reliability
|| self.destination_order != other.destination_order
|| self.history != other.history
|| self.resource_limits != other.resource_limits
|| self.ownership != other.ownership
{
Err(DdsError::ImmutablePolicy)
} else {
Ok(())
}
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct TopicQos {
pub topic_data: TopicDataQosPolicy,
pub durability: DurabilityQosPolicy,
pub deadline: DeadlineQosPolicy,
pub latency_budget: LatencyBudgetQosPolicy,
pub liveliness: LivelinessQosPolicy,
pub reliability: ReliabilityQosPolicy,
pub destination_order: DestinationOrderQosPolicy,
pub history: HistoryQosPolicy,
pub resource_limits: ResourceLimitsQosPolicy,
pub transport_priority: TransportPriorityQosPolicy,
pub lifespan: LifespanQosPolicy,
pub ownership: OwnershipQosPolicy,
pub representation: DataRepresentationQosPolicy,
}
impl TopicQos {
pub const fn const_default() -> Self {
Self {
reliability: ReliabilityQosPolicy {
kind: ReliabilityQosPolicyKind::BestEffort,
max_blocking_time: DurationKind::Finite(Duration::new(
0,
100_000_000,
)),
},
topic_data: TopicDataQosPolicy::const_default(),
durability: DurabilityQosPolicy::const_default(),
deadline: DeadlineQosPolicy::const_default(),
latency_budget: LatencyBudgetQosPolicy::const_default(),
liveliness: LivelinessQosPolicy::const_default(),
destination_order: DestinationOrderQosPolicy::const_default(),
history: HistoryQosPolicy::const_default(),
resource_limits: ResourceLimitsQosPolicy::const_default(),
transport_priority: TransportPriorityQosPolicy::const_default(),
lifespan: LifespanQosPolicy::const_default(),
ownership: OwnershipQosPolicy::const_default(),
representation: DataRepresentationQosPolicy::const_default(),
}
}
}
impl Default for TopicQos {
fn default() -> Self {
Self::const_default()
}
}
impl TopicQos {
pub(crate) fn is_consistent(&self) -> DdsResult<()> {
if self.resource_limits.max_samples < self.resource_limits.max_samples_per_instance {
return Err(DdsError::InconsistentPolicy);
}
match self.history.kind {
HistoryQosPolicyKind::KeepLast(depth) => {
if depth as usize > self.resource_limits.max_samples_per_instance {
Err(DdsError::InconsistentPolicy)
} else {
Ok(())
}
}
HistoryQosPolicyKind::KeepAll => Ok(()),
}
}
}
#[cfg(test)]
mod tests {
use crate::infrastructure::qos_policy::Length;
use super::*;
#[test]
fn data_writer_qos_consistency() {
assert_eq!(DataWriterQos::default().is_consistent(), Ok(()));
assert_eq!(
DataWriterQos {
resource_limits: ResourceLimitsQosPolicy {
max_samples_per_instance: Length::Limited(2),
max_samples: Length::Limited(1),
..Default::default()
},
..Default::default()
}
.is_consistent(),
Err(DdsError::InconsistentPolicy)
);
assert_eq!(
DataWriterQos {
history: HistoryQosPolicy {
kind: HistoryQosPolicyKind::KeepLast(3),
},
resource_limits: ResourceLimitsQosPolicy {
max_samples_per_instance: Length::Limited(2),
..Default::default()
},
..Default::default()
}
.is_consistent(),
Err(DdsError::InconsistentPolicy)
);
}
#[test]
fn data_reader_qos_consistency() {
assert_eq!(DataReaderQos::default().is_consistent(), Ok(()));
assert_eq!(
DataReaderQos {
resource_limits: ResourceLimitsQosPolicy {
max_samples_per_instance: Length::Limited(2),
max_samples: Length::Limited(1),
..Default::default()
},
..Default::default()
}
.is_consistent(),
Err(DdsError::InconsistentPolicy)
);
assert_eq!(
DataReaderQos {
history: HistoryQosPolicy {
kind: HistoryQosPolicyKind::KeepLast(3),
},
resource_limits: ResourceLimitsQosPolicy {
max_samples_per_instance: Length::Limited(2),
..Default::default()
},
..Default::default()
}
.is_consistent(),
Err(DdsError::InconsistentPolicy)
);
}
#[test]
fn topic_qos_consistency() {
assert_eq!(TopicQos::default().is_consistent(), Ok(()));
assert_eq!(
TopicQos {
resource_limits: ResourceLimitsQosPolicy {
max_samples_per_instance: Length::Limited(2),
max_samples: Length::Limited(1),
..Default::default()
},
..Default::default()
}
.is_consistent(),
Err(DdsError::InconsistentPolicy)
);
assert_eq!(
TopicQos {
history: HistoryQosPolicy {
kind: HistoryQosPolicyKind::KeepLast(3),
},
resource_limits: ResourceLimitsQosPolicy {
max_samples_per_instance: Length::Limited(2),
..Default::default()
},
..Default::default()
}
.is_consistent(),
Err(DdsError::InconsistentPolicy)
);
}
}