use std::time::{Duration, SystemTime};
use crate::rcl_bindings::*;
#[derive(Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct PublisherGid {
pub data: [u8; RMW_GID_STORAGE_SIZE],
pub implementation_identifier: *const std::os::raw::c_char,
}
unsafe impl Send for PublisherGid {}
unsafe impl Sync for PublisherGid {}
#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct MessageInfo {
pub source_timestamp: Option<SystemTime>,
pub received_timestamp: Option<SystemTime>,
pub publication_sequence_number: u64,
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 {
Self {
source_timestamp: timestamp_to_system_time(rmw_message_info.source_timestamp),
received_timestamp: timestamp_to_system_time(rmw_message_info.received_timestamp),
publication_sequence_number: rmw_message_info.publication_sequence_number,
reception_sequence_number: rmw_message_info.reception_sequence_number,
publisher_gid: PublisherGid {
data: rmw_message_info.publisher_gid.data,
implementation_identifier: rmw_message_info.publisher_gid.implementation_identifier,
},
}
}
}
pub(crate) fn timestamp_to_system_time(timestamp: rmw_time_point_value_t) -> Option<SystemTime> {
match 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())),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[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; RMW_GID_STORAGE_SIZE],
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()
);
}
#[test]
fn traits() {
use crate::test_helpers::*;
assert_send::<MessageInfo>();
assert_sync::<MessageInfo>();
}
}