extern crate alloc;
use alloc::vec::Vec;
use crate::instance_handle::InstanceHandle;
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct InconsistentTopicStatus {
pub total_count: i32,
pub total_count_change: i32,
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SampleLostStatus {
pub total_count: i32,
pub total_count_change: i32,
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct LivelinessLostStatus {
pub total_count: i32,
pub total_count_change: i32,
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct OfferedDeadlineMissedStatus {
pub total_count: i32,
pub total_count_change: i32,
pub last_instance_handle: InstanceHandle,
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct RequestedDeadlineMissedStatus {
pub total_count: i32,
pub total_count_change: i32,
pub last_instance_handle: InstanceHandle,
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub enum SampleRejectedStatusKind {
#[default]
NotRejected,
RejectedByInstancesLimit,
RejectedBySamplesLimit,
RejectedBySamplesPerInstanceLimit,
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SampleRejectedStatus {
pub total_count: i32,
pub total_count_change: i32,
pub last_reason: SampleRejectedStatusKind,
pub last_instance_handle: InstanceHandle,
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct LivelinessChangedStatus {
pub alive_count: i32,
pub not_alive_count: i32,
pub alive_count_change: i32,
pub not_alive_count_change: i32,
pub last_publication_handle: InstanceHandle,
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct PublicationMatchedStatus {
pub total_count: i32,
pub total_count_change: i32,
pub current_count: i32,
pub current_count_change: i32,
pub last_subscription_handle: InstanceHandle,
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SubscriptionMatchedStatus {
pub total_count: i32,
pub total_count_change: i32,
pub current_count: i32,
pub current_count_change: i32,
pub last_publication_handle: InstanceHandle,
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct QosPolicyCount {
pub policy_id: u32,
pub count: i32,
}
impl QosPolicyCount {
#[must_use]
pub const fn new(policy_id: u32, count: i32) -> Self {
Self { policy_id, count }
}
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct OfferedIncompatibleQosStatus {
pub total_count: i32,
pub total_count_change: i32,
pub last_policy_id: u32,
pub policies: Vec<QosPolicyCount>,
}
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct RequestedIncompatibleQosStatus {
pub total_count: i32,
pub total_count_change: i32,
pub last_policy_id: u32,
pub policies: Vec<QosPolicyCount>,
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct DataAvailableStatus;
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub struct DataOnReadersStatus;
pub fn bump_policy_count(policies: &mut Vec<QosPolicyCount>, policy_id: u32) {
if let Some(slot) = policies.iter_mut().find(|p| p.policy_id == policy_id) {
slot.count = slot.count.saturating_add(1);
return;
}
policies.push(QosPolicyCount::new(policy_id, 1));
}
#[cfg(test)]
#[allow(clippy::expect_used, clippy::unwrap_used)]
mod tests {
use super::*;
use crate::psm_constants::qos_policy_id;
#[test]
fn inconsistent_topic_default_is_zero() {
let s = InconsistentTopicStatus::default();
assert_eq!(s.total_count, 0);
assert_eq!(s.total_count_change, 0);
}
#[test]
fn sample_lost_clone_roundtrip() {
let s = SampleLostStatus {
total_count: 5,
total_count_change: 2,
};
let c = s;
assert_eq!(s, c);
}
#[test]
fn sample_rejected_status_default_kind_is_not_rejected() {
let s = SampleRejectedStatus::default();
assert_eq!(s.last_reason, SampleRejectedStatusKind::NotRejected);
assert!(s.last_instance_handle.is_nil());
}
#[test]
fn sample_rejected_kind_variants_are_distinct() {
let kinds = [
SampleRejectedStatusKind::NotRejected,
SampleRejectedStatusKind::RejectedByInstancesLimit,
SampleRejectedStatusKind::RejectedBySamplesLimit,
SampleRejectedStatusKind::RejectedBySamplesPerInstanceLimit,
];
for (i, a) in kinds.iter().enumerate() {
for b in &kinds[i + 1..] {
assert_ne!(a, b);
}
}
}
#[test]
fn liveliness_lost_default() {
let s = LivelinessLostStatus::default();
assert_eq!(s.total_count, 0);
}
#[test]
fn liveliness_changed_negative_count_change_allowed() {
let s = LivelinessChangedStatus {
alive_count: 0,
not_alive_count: 1,
alive_count_change: -1,
not_alive_count_change: 1,
last_publication_handle: InstanceHandle::from_raw(42),
};
assert_eq!(s.alive_count_change, -1);
assert_eq!(s.not_alive_count_change, 1);
assert_eq!(s.last_publication_handle.as_raw(), 42);
}
#[test]
fn publication_matched_with_handle_roundtrip() {
let h = InstanceHandle::from_raw(99);
let s = PublicationMatchedStatus {
total_count: 3,
total_count_change: 1,
current_count: 2,
current_count_change: 1,
last_subscription_handle: h,
};
let c = s;
assert_eq!(c.last_subscription_handle, h);
assert_eq!(c.current_count, 2);
}
#[test]
fn subscription_matched_with_handle_roundtrip() {
let h = InstanceHandle::from_raw(7);
let s = SubscriptionMatchedStatus {
total_count: 5,
total_count_change: 0,
current_count: 5,
current_count_change: 0,
last_publication_handle: h,
};
assert_eq!(s.last_publication_handle, h);
}
#[test]
fn offered_deadline_missed_default_handle_is_nil() {
let s = OfferedDeadlineMissedStatus::default();
assert!(s.last_instance_handle.is_nil());
}
#[test]
fn requested_deadline_missed_default_handle_is_nil() {
let s = RequestedDeadlineMissedStatus::default();
assert!(s.last_instance_handle.is_nil());
}
#[test]
fn offered_incompatible_qos_clone_roundtrip() {
let s = OfferedIncompatibleQosStatus {
total_count: 2,
total_count_change: 1,
last_policy_id: qos_policy_id::DURABILITY,
policies: alloc::vec![QosPolicyCount::new(qos_policy_id::DURABILITY, 2)],
};
let c = s.clone();
assert_eq!(c, s);
assert_eq!(c.policies.len(), 1);
assert_eq!(c.policies[0].policy_id, qos_policy_id::DURABILITY);
}
#[test]
fn requested_incompatible_qos_clone_roundtrip() {
let s = RequestedIncompatibleQosStatus {
total_count: 1,
total_count_change: 1,
last_policy_id: qos_policy_id::RELIABILITY,
policies: alloc::vec![QosPolicyCount::new(qos_policy_id::RELIABILITY, 1)],
};
let c = s.clone();
assert_eq!(c, s);
}
#[test]
fn bump_policy_count_inserts_then_increments() {
let mut v = alloc::vec::Vec::<QosPolicyCount>::new();
bump_policy_count(&mut v, qos_policy_id::DURABILITY);
assert_eq!(v.len(), 1);
assert_eq!(v[0].count, 1);
bump_policy_count(&mut v, qos_policy_id::DURABILITY);
assert_eq!(v.len(), 1);
assert_eq!(v[0].count, 2);
bump_policy_count(&mut v, qos_policy_id::RELIABILITY);
assert_eq!(v.len(), 2);
}
#[test]
fn data_available_and_data_on_readers_are_zero_sized_markers() {
let a1 = DataAvailableStatus;
let a2 = DataAvailableStatus;
assert_eq!(a1, a2);
let r1 = DataOnReadersStatus;
let r2 = DataOnReadersStatus;
assert_eq!(r1, r2);
assert_eq!(core::mem::size_of::<DataAvailableStatus>(), 0);
assert_eq!(core::mem::size_of::<DataOnReadersStatus>(), 0);
}
}