use std::time::{Duration, SystemTime};
use crate::rcl_bindings::*;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct PublisherGid {
pub data: [u8; 24],
pub implementation_identifier: *const std::os::raw::c_char,
}
unsafe impl Send for PublisherGid {}
unsafe impl Sync for PublisherGid {}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct MessageInfo {
pub source_timestamp: Option<SystemTime>,
pub received_timestamp: Option<SystemTime>,
#[cfg(all(not(ros_distro = "foxy"), not(ros_distro = "galactic")))]
pub publication_sequence_number: u64,
#[cfg(all(not(ros_distro = "foxy"), not(ros_distro = "galactic")))]
pub reception_sequence_number: u64,
pub publisher_gid: PublisherGid,
}
impl MessageInfo {
pub(crate) fn from_rmw_message_info(rmw_message_info: &rmw_message_info_t) -> Self {
let source_timestamp = match rmw_message_info.source_timestamp {
0 => None,
ts if ts < 0 => Some(SystemTime::UNIX_EPOCH - Duration::from_nanos(ts.unsigned_abs())),
ts => Some(SystemTime::UNIX_EPOCH + Duration::from_nanos(ts.unsigned_abs())),
};
let received_timestamp = match rmw_message_info.received_timestamp {
0 => None,
ts if ts < 0 => Some(SystemTime::UNIX_EPOCH - Duration::from_nanos(ts.unsigned_abs())),
ts => Some(SystemTime::UNIX_EPOCH + Duration::from_nanos(ts.unsigned_abs())),
};
let publisher_gid = PublisherGid {
data: rmw_message_info.publisher_gid.data,
implementation_identifier: rmw_message_info.publisher_gid.implementation_identifier,
};
Self {
source_timestamp,
received_timestamp,
#[cfg(all(not(ros_distro = "foxy"), not(ros_distro = "galactic")))]
publication_sequence_number: rmw_message_info.publication_sequence_number,
#[cfg(all(not(ros_distro = "foxy"), not(ros_distro = "galactic")))]
reception_sequence_number: rmw_message_info.reception_sequence_number,
publisher_gid,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(all(not(ros_distro = "foxy"), not(ros_distro = "galactic")))]
#[test]
fn negative_durations() {
let rmw_message_info = rmw_message_info_t {
source_timestamp: -1_000_000_000,
received_timestamp: 1_000_000_000,
publication_sequence_number: 0,
reception_sequence_number: 0,
publisher_gid: rmw_gid_t {
data: [0; 24],
implementation_identifier: std::ptr::null(),
},
from_intra_process: false,
};
let message_info = MessageInfo::from_rmw_message_info(&rmw_message_info);
assert_eq!(
message_info.source_timestamp.unwrap() + Duration::from_nanos(2_000_000_000),
message_info.received_timestamp.unwrap()
);
}
fn assert_send<T: Send>() {}
fn assert_sync<T: Sync>() {}
#[test]
fn wait_set_is_send_and_sync() {
assert_send::<MessageInfo>();
assert_sync::<MessageInfo>();
}
}