pub mod builtin;
pub mod sensor_msgs;
pub mod std_msgs;
use core::fmt::Display;
use serde::Serialize;
use serde::de::DeserializeOwned;
use std::convert::From;
#[macro_export]
macro_rules! ros_type_name {
($t:ty) => {{ std::any::type_name::<$t>().rsplit("::").next().unwrap() }};
}
pub trait RosMsgAdapter<'a>: Sized {
type Output: Serialize + for<'b> From<&'b Self>;
fn namespace() -> &'a str;
fn type_name() -> &'a str {
ros_type_name!(Self::Output)
}
fn type_hash() -> &'static str;
}
pub trait RosBridgeAdapter: Sized + 'static {
type RosMessage: Serialize + DeserializeOwned + 'static;
fn namespace() -> &'static str;
fn type_name() -> &'static str {
ros_type_name!(Self::RosMessage)
}
fn type_hash() -> &'static str;
fn to_ros_message(&self) -> Self::RosMessage;
fn from_ros_message(msg: Self::RosMessage) -> Result<Self, String>;
}
impl<T> RosBridgeAdapter for T
where
T: RosMsgAdapter<'static> + TryFrom<<T as RosMsgAdapter<'static>>::Output> + 'static,
T::Output: Serialize + DeserializeOwned + 'static,
<T as TryFrom<<T as RosMsgAdapter<'static>>::Output>>::Error: Display,
{
type RosMessage = <T as RosMsgAdapter<'static>>::Output;
fn namespace() -> &'static str {
<T as RosMsgAdapter<'static>>::namespace()
}
fn type_name() -> &'static str {
<T as RosMsgAdapter<'static>>::type_name()
}
#[cfg(not(feature = "humble"))]
fn type_hash() -> &'static str {
<T as RosMsgAdapter<'static>>::type_hash()
}
#[cfg(feature = "humble")]
fn type_hash() -> &'static str {
"TypeHashNotSupported"
}
fn to_ros_message(&self) -> Self::RosMessage {
self.into()
}
fn from_ros_message(msg: Self::RosMessage) -> Result<Self, String> {
T::try_from(msg).map_err(|e| e.to_string())
}
}