use crate::Result;
use std::ffi::c_void;
pub trait TypeSupport: 'static + Send + Sync {
fn type_support() -> *const c_void {
std::ptr::null()
}
fn to_bytes(&self) -> Result<Vec<u8>>;
fn from_bytes(bytes: &[u8]) -> Result<Self>
where
Self: Sized;
fn type_name() -> &'static str;
fn type_hash() -> Result<::std::string::String> {
Ok("RIHS01_00".to_string())
}
}
pub trait TryClone: Sized {
fn try_clone(&self) -> Option<Self>;
}
pub trait ServiceMsg: 'static + Send + Sync {
type Request: TypeSupport;
type Response: TypeSupport;
fn type_support() -> *const c_void {
std::ptr::null()
}
fn type_name() -> &'static str;
fn type_hash() -> Result<::std::string::String> {
Ok("RIHS01_00".to_string())
}
}
pub trait ActionMsg: 'static + Send + Sync {
type Goal: ActionGoal;
type Result: ActionResult;
type Feedback: TypeSupport + GetUUID;
fn type_support() -> *const c_void {
std::ptr::null()
}
fn type_name() -> &'static str;
type GoalContent: TypeSupport;
fn new_goal_request(
goal: Self::GoalContent,
uuid: [u8; 16],
) -> <Self::Goal as ActionGoal>::Request;
type ResultContent: TypeSupport + TryClone;
fn new_result_response(
status: u8,
result: Self::ResultContent,
) -> <Self::Result as ActionResult>::Response;
type FeedbackContent: TypeSupport;
fn new_feedback_message(feedback: Self::FeedbackContent, uuid: [u8; 16]) -> Self::Feedback;
fn type_hash() -> Result<::std::string::String> {
Ok("RIHS01_00".to_string())
}
}
pub trait ActionGoal: 'static + Send + Sync {
type Request: TypeSupport + GetUUID;
type Response: TypeSupport + GoalResponse;
fn type_support() -> *const c_void {
std::ptr::null()
}
}
pub trait GetUUID: 'static + Send + Sync {
fn get_uuid(&self) -> &[u8; 16];
}
pub trait GoalResponse: 'static + Send + Sync {
fn is_accepted(&self) -> bool;
fn get_time_stamp(&self) -> UnsafeTime;
fn new(accepted: bool, stamp: UnsafeTime) -> Self;
}
pub trait ActionResult: 'static + Send + Sync {
type Request: TypeSupport + GetUUID;
type Response: TypeSupport + ResultResponse;
fn type_support() -> *const c_void {
std::ptr::null()
}
}
pub trait ResultResponse: 'static + Send + Sync {
fn get_status(&self) -> u8;
}
#[repr(C)]
#[derive(
Debug,
Clone,
Copy,
Default,
PartialEq,
Eq,
PartialOrd,
Ord,
serde::Serialize,
serde::Deserialize,
)]
pub struct UnsafeTime {
pub sec: i32,
pub nanosec: u32,
}
impl UnsafeTime {
pub const fn new(sec: i32, nanosec: u32) -> Self {
Self { sec, nanosec }
}
pub const fn zero() -> Self {
Self { sec: 0, nanosec: 0 }
}
}
use std::time::{Duration, SystemTime};
impl From<&SystemTime> for UnsafeTime {
fn from(t: &SystemTime) -> Self {
let dur = t.duration_since(SystemTime::UNIX_EPOCH).unwrap();
let sec = dur.as_secs();
if sec > i32::MAX as u64 {
panic!("SystemTime too far in future (year-2038 problem)");
}
UnsafeTime {
sec: sec as i32,
nanosec: dur.subsec_nanos(),
}
}
}
impl From<SystemTime> for UnsafeTime {
fn from(t: SystemTime) -> Self {
(&t).into()
}
}
impl From<&UnsafeTime> for SystemTime {
fn from(t: &UnsafeTime) -> Self {
let nanos = Duration::from_nanos(t.nanosec as u64);
let secs = Duration::from_secs(t.sec as u64);
let dur = nanos + secs;
SystemTime::UNIX_EPOCH + dur
}
}
impl From<UnsafeTime> for SystemTime {
fn from(t: UnsafeTime) -> Self {
(&t).into()
}
}
#[repr(C)]
#[derive(
Debug,
Clone,
Copy,
Default,
PartialEq,
Eq,
PartialOrd,
Ord,
serde::Serialize,
serde::Deserialize,
)]
pub struct UnsafeDuration {
pub sec: i32,
pub nanosec: u32,
}
impl UnsafeDuration {
pub const fn new(sec: i32, nanosec: u32) -> Self {
Self { sec, nanosec }
}
pub const fn zero() -> Self {
Self { sec: 0, nanosec: 0 }
}
}
impl From<&Duration> for UnsafeDuration {
fn from(t: &Duration) -> Self {
let sec = t.as_secs();
if sec > i32::MAX as u64 {
panic!("Duration too long (year-2038 problem)");
}
let nanosec = t.subsec_nanos();
UnsafeDuration {
sec: sec as i32,
nanosec,
}
}
}
impl From<Duration> for UnsafeDuration {
fn from(t: Duration) -> Self {
(&t).into()
}
}
impl From<&UnsafeDuration> for Duration {
fn from(t: &UnsafeDuration) -> Self {
Duration::from_secs(t.sec as u64) + Duration::from_nanos(t.nanosec as u64)
}
}
impl From<UnsafeDuration> for Duration {
fn from(t: UnsafeDuration) -> Self {
(&t).into()
}
}
#[repr(C)]
#[derive(Debug)]
pub struct SequenceRaw<T> {
pub data: *mut T,
pub size: usize,
pub capacity: usize,
}
impl<T> SequenceRaw<T> {
pub const fn null() -> Self {
Self {
data: std::ptr::null_mut(),
size: 0,
capacity: 0,
}
}
pub fn is_empty(&self) -> bool {
self.size == 0
}
pub fn len(&self) -> usize {
self.size
}
pub fn as_slice(&self) -> &[T] {
if self.data.is_null() || self.size == 0 {
&[]
} else {
unsafe { std::slice::from_raw_parts(self.data, self.size) }
}
}
pub fn iter(&self) -> std::slice::Iter<'_, T> {
self.as_slice().iter()
}
#[deprecated(note = "use as_mut_slice instead")]
pub fn as_slice_mut(&mut self) -> &mut [T] {
if self.data.is_null() || self.size == 0 {
&mut []
} else {
unsafe { std::slice::from_raw_parts_mut(self.data, self.size) }
}
}
pub fn as_mut_slice(&mut self) -> &mut [T] {
if self.data.is_null() || self.size == 0 {
&mut []
} else {
unsafe { std::slice::from_raw_parts_mut(self.data, self.size) }
}
}
pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> {
self.as_mut_slice().iter_mut()
}
}
#[cfg(not(feature = "rcl"))]
impl<T> SequenceRaw<T> {
pub fn from_vec(mut vec: Vec<T>) -> Self {
let data = vec.as_mut_ptr();
let size = vec.len();
let capacity = vec.capacity();
std::mem::forget(vec); Self {
data,
size,
capacity,
}
}
pub unsafe fn into_vec(self) -> Vec<T> {
if self.data.is_null() {
Vec::new()
} else {
let vec = unsafe { Vec::from_raw_parts(self.data, self.size, self.capacity) };
std::mem::forget(self); vec
}
}
}
#[cfg(not(feature = "rcl"))]
impl<T: Clone> Clone for SequenceRaw<T> {
fn clone(&self) -> Self {
if self.data.is_null() || self.size == 0 {
Self::null()
} else {
let slice = unsafe { std::slice::from_raw_parts(self.data, self.size) };
let vec: Vec<T> = slice.to_vec();
Self::from_vec(vec)
}
}
}
#[cfg(feature = "rcl")]
impl<T> Clone for SequenceRaw<T> {
fn clone(&self) -> Self {
Self {
data: self.data,
size: self.size,
capacity: self.capacity,
}
}
}
impl<T: PartialEq> PartialEq for SequenceRaw<T> {
fn eq(&self, other: &Self) -> bool {
if self.size != other.size {
return false;
}
if self.data.is_null() && other.data.is_null() {
return true;
}
if self.data.is_null() || other.data.is_null() {
return false;
}
let self_slice = unsafe { std::slice::from_raw_parts(self.data, self.size) };
let other_slice = unsafe { std::slice::from_raw_parts(other.data, other.size) };
self_slice == other_slice
}
}
impl<T> Default for SequenceRaw<T> {
fn default() -> Self {
Self::null()
}
}
#[cfg(not(feature = "rcl"))]
impl<T> Drop for SequenceRaw<T> {
fn drop(&mut self) {
if !self.data.is_null() && self.capacity > 0 {
unsafe {
let _ = Vec::from_raw_parts(self.data, self.size, self.capacity);
}
}
}
}
#[cfg(not(feature = "rcl"))]
impl<T: serde::Serialize> serde::Serialize for SequenceRaw<T> {
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeSeq;
let slice = self.as_slice();
let mut seq = serializer.serialize_seq(Some(slice.len()))?;
for element in slice {
seq.serialize_element(element)?;
}
seq.end()
}
}
#[cfg(not(feature = "rcl"))]
impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for SequenceRaw<T> {
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let vec = Vec::<T>::deserialize(deserializer)?;
Ok(Self::from_vec(vec))
}
}
unsafe impl<T: Send> Send for SequenceRaw<T> {}
unsafe impl<T: Sync> Sync for SequenceRaw<T> {}