#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Reliability {
Reliable,
BestEffort,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Durability {
Volatile,
TransientLocal,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum History {
KeepLast(u32),
KeepAll,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct QosProfile {
pub reliability: Reliability,
pub durability: Durability,
pub history: History,
pub liveliness_lease_secs: Option<u32>,
pub deadline_secs: Option<u32>,
}
pub mod profiles {
use super::*;
pub const DEFAULT: QosProfile = QosProfile {
reliability: Reliability::Reliable,
durability: Durability::Volatile,
history: History::KeepLast(10),
liveliness_lease_secs: None,
deadline_secs: None,
};
pub const SENSOR_DATA: QosProfile = QosProfile {
reliability: Reliability::BestEffort,
durability: Durability::Volatile,
history: History::KeepLast(5),
liveliness_lease_secs: None,
deadline_secs: None,
};
pub const MAP: QosProfile = QosProfile {
reliability: Reliability::Reliable,
durability: Durability::TransientLocal,
history: History::KeepLast(1),
liveliness_lease_secs: None,
deadline_secs: None,
};
pub const PARAMETERS: QosProfile = QosProfile {
reliability: Reliability::Reliable,
durability: Durability::Volatile,
history: History::KeepLast(1000),
liveliness_lease_secs: None,
deadline_secs: None,
};
pub const SERVICES_DEFAULT: QosProfile = QosProfile {
reliability: Reliability::Reliable,
durability: Durability::Volatile,
history: History::KeepLast(10),
liveliness_lease_secs: None,
deadline_secs: None,
};
pub const PARAMETER_EVENTS: QosProfile = QosProfile {
reliability: Reliability::Reliable,
durability: Durability::Volatile,
history: History::KeepLast(1000),
liveliness_lease_secs: None,
deadline_secs: None,
};
pub const SYSTEM_DEFAULT: QosProfile = DEFAULT;
pub const UNKNOWN: QosProfile = QosProfile {
reliability: Reliability::BestEffort,
durability: Durability::Volatile,
history: History::KeepLast(0),
liveliness_lease_secs: None,
deadline_secs: None,
};
#[must_use]
pub fn is_unknown(p: &QosProfile) -> bool {
matches!(p.history, History::KeepLast(0))
&& p.reliability == Reliability::BestEffort
&& p.liveliness_lease_secs.is_none()
&& p.deadline_secs.is_none()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_profile_is_reliable_volatile_keep_last_10() {
let p = profiles::DEFAULT;
assert_eq!(p.reliability, Reliability::Reliable);
assert_eq!(p.durability, Durability::Volatile);
assert_eq!(p.history, History::KeepLast(10));
}
#[test]
fn sensor_data_profile_matches_rep_2003_specification() {
let p = profiles::SENSOR_DATA;
assert_eq!(p.reliability, Reliability::BestEffort);
assert_eq!(p.durability, Durability::Volatile);
assert_eq!(p.history, History::KeepLast(5));
}
#[test]
fn map_profile_matches_rep_2003_specification() {
let p = profiles::MAP;
assert_eq!(p.reliability, Reliability::Reliable);
assert_eq!(p.durability, Durability::TransientLocal);
assert_eq!(p.history, History::KeepLast(1));
}
#[test]
fn parameters_profile_uses_keep_last_1000() {
let p = profiles::PARAMETERS;
assert_eq!(p.history, History::KeepLast(1000));
assert_eq!(p.reliability, Reliability::Reliable);
}
#[test]
fn services_default_matches_rmw_defaults() {
let p = profiles::SERVICES_DEFAULT;
assert_eq!(p.reliability, Reliability::Reliable);
assert_eq!(p.history, History::KeepLast(10));
}
#[test]
fn parameter_events_uses_keep_last_1000() {
let p = profiles::PARAMETER_EVENTS;
assert_eq!(p.history, History::KeepLast(1000));
}
#[test]
fn system_default_aliases_default() {
assert_eq!(profiles::SYSTEM_DEFAULT, profiles::DEFAULT);
}
#[test]
fn history_keep_last_distinct_from_keep_all() {
assert_ne!(History::KeepLast(10), History::KeepAll);
assert_ne!(History::KeepLast(1), History::KeepLast(2));
}
#[test]
fn liveliness_and_deadline_default_to_infinite() {
assert_eq!(profiles::DEFAULT.liveliness_lease_secs, None);
assert_eq!(profiles::DEFAULT.deadline_secs, None);
}
#[test]
fn unknown_profile_is_distinct_from_default() {
assert_ne!(profiles::UNKNOWN, profiles::DEFAULT);
}
#[test]
fn unknown_profile_uses_keep_last_zero_marker() {
assert_eq!(profiles::UNKNOWN.history, History::KeepLast(0));
}
#[test]
fn is_unknown_recognizes_unknown_profile() {
assert!(profiles::is_unknown(&profiles::UNKNOWN));
}
#[test]
fn is_unknown_rejects_real_profiles() {
assert!(!profiles::is_unknown(&profiles::DEFAULT));
assert!(!profiles::is_unknown(&profiles::SENSOR_DATA));
}
}