extern crate alloc;
use alloc::string::String;
use alloc::vec::Vec;
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct PublicationBuiltinTopicDataExt {
pub service_name: String,
pub mapping_profile: ServiceMappingProfile,
pub topic_aliases: Vec<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct SubscriptionBuiltinTopicDataExt {
pub service_name: String,
pub mapping_profile: ServiceMappingProfile,
pub topic_aliases: Vec<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum ServiceMappingProfile {
#[default]
Basic,
Enhanced,
}
#[must_use]
pub fn client_matches_service(
client_pub_data: &PublicationBuiltinTopicDataExt,
service_sub_data: &SubscriptionBuiltinTopicDataExt,
) -> bool {
if client_pub_data.service_name != service_sub_data.service_name {
return false;
}
profile_compatible(
client_pub_data.mapping_profile,
service_sub_data.mapping_profile,
)
}
#[must_use]
pub fn service_matches_client(
service_pub_data: &PublicationBuiltinTopicDataExt,
client_sub_data: &SubscriptionBuiltinTopicDataExt,
) -> bool {
if service_pub_data.service_name != client_sub_data.service_name {
return false;
}
profile_compatible(
service_pub_data.mapping_profile,
client_sub_data.mapping_profile,
)
}
fn profile_compatible(a: ServiceMappingProfile, b: ServiceMappingProfile) -> bool {
a == b
}
#[cfg(test)]
#[allow(clippy::expect_used)]
mod tests {
use super::*;
fn pub_data(name: &str, profile: ServiceMappingProfile) -> PublicationBuiltinTopicDataExt {
PublicationBuiltinTopicDataExt {
service_name: name.into(),
mapping_profile: profile,
topic_aliases: Vec::new(),
}
}
fn sub_data(name: &str, profile: ServiceMappingProfile) -> SubscriptionBuiltinTopicDataExt {
SubscriptionBuiltinTopicDataExt {
service_name: name.into(),
mapping_profile: profile,
topic_aliases: Vec::new(),
}
}
#[test]
fn client_matches_service_with_same_name_and_profile() {
let p = pub_data("Calc", ServiceMappingProfile::Basic);
let s = sub_data("Calc", ServiceMappingProfile::Basic);
assert!(client_matches_service(&p, &s));
}
#[test]
fn client_does_not_match_service_with_different_name() {
let p = pub_data("Calc", ServiceMappingProfile::Basic);
let s = sub_data("Other", ServiceMappingProfile::Basic);
assert!(!client_matches_service(&p, &s));
}
#[test]
fn client_does_not_match_service_with_different_profile() {
let p = pub_data("Calc", ServiceMappingProfile::Basic);
let s = sub_data("Calc", ServiceMappingProfile::Enhanced);
assert!(!client_matches_service(&p, &s));
}
#[test]
fn service_matches_client_symmetric() {
let p = pub_data("Calc", ServiceMappingProfile::Enhanced);
let s = sub_data("Calc", ServiceMappingProfile::Enhanced);
assert!(service_matches_client(&p, &s));
}
#[test]
fn topic_aliases_propagated_in_extended_data() {
let p = PublicationBuiltinTopicDataExt {
service_name: "Inherited".into(),
mapping_profile: ServiceMappingProfile::Enhanced,
topic_aliases: alloc::vec!["BaseInterface_Request".into()],
};
assert_eq!(p.topic_aliases.len(), 1);
assert_eq!(p.topic_aliases[0], "BaseInterface_Request");
}
}