use crate::topic_name::*;
use crate::{Result, ServiceError};
use std::future::Future;
pub trait RosMessageType:
'static + serde::de::DeserializeOwned + Send + serde::Serialize + Sync + Clone + std::fmt::Debug
{
const ROS_TYPE_NAME: &'static str;
const MD5SUM: &'static str = "";
const DEFINITION: &'static str = "";
const ROS2_TYPE_NAME: &'static str = "";
const ROS2_HASH: &'static [u8; 32] = &[0; 32];
}
impl RosMessageType for () {
const ROS_TYPE_NAME: &'static str = "";
const MD5SUM: &'static str = "";
const DEFINITION: &'static str = "";
}
pub trait RosServiceType: 'static + Send + Sync {
const ROS_SERVICE_NAME: &'static str;
const MD5SUM: &'static str = "";
const ROS2_HASH: &'static [u8; 32] = &[0; 32];
const ROS2_TYPE_NAME: &'static str = "";
type Request: RosMessageType;
type Response: RosMessageType;
}
pub trait ServiceFn<T: RosServiceType>:
Fn(T::Request) -> std::result::Result<T::Response, ServiceError> + Send + Sync + 'static
{
}
impl<T, F> ServiceFn<T> for F
where
T: RosServiceType,
F: Fn(T::Request) -> std::result::Result<T::Response, ServiceError> + Send + Sync + 'static,
{
}
pub trait Publish<T: RosMessageType> {
fn publish(&self, data: &T) -> impl Future<Output = Result<()>> + Send;
}
pub trait Subscribe<T: RosMessageType>
where
Self: Sized,
{
fn next(&mut self) -> impl Future<Output = Result<T>> + Send;
fn into_stream(mut self) -> impl futures_core::Stream<Item = Result<T>> {
use async_stream::stream;
stream! {
loop {
yield self.next().await;
}
}
}
}
pub trait TopicProvider {
type Publisher<T: RosMessageType>: Publish<T> + Send + Sync + 'static;
type Subscriber<T: RosMessageType>: Subscribe<T> + Send + Sync + 'static;
fn advertise<MsgType: RosMessageType>(
&self,
topic: impl ToGlobalTopicName,
) -> impl Future<Output = Result<Self::Publisher<MsgType>>> + Send;
fn subscribe<MsgType: RosMessageType>(
&self,
topic: impl ToGlobalTopicName,
) -> impl Future<Output = Result<Self::Subscriber<MsgType>>> + Send;
}
pub trait Service<T: RosServiceType> {
fn call(&self, request: &T::Request) -> impl Future<Output = Result<T::Response>> + Send;
}
pub trait ServiceProvider {
type ServiceClient<T: RosServiceType>: Service<T> + Send + Sync + 'static;
type ServiceServer: Send + Sync + 'static;
fn call_service<SrvType: RosServiceType>(
&self,
service: impl ToGlobalTopicName,
request: SrvType::Request,
) -> impl Future<Output = Result<SrvType::Response>> + Send;
fn service_client<SrvType: RosServiceType + 'static>(
&self,
service: impl ToGlobalTopicName,
) -> impl Future<Output = Result<Self::ServiceClient<SrvType>>> + Send;
fn advertise_service<SrvType: RosServiceType + 'static, F: ServiceFn<SrvType>>(
&self,
service: impl ToGlobalTopicName,
server: F,
) -> impl Future<Output = Result<Self::ServiceServer>> + Send;
}
pub trait Ros: 'static + Send + Sync + TopicProvider + ServiceProvider + Clone {}
impl<T: 'static + Send + Sync + TopicProvider + ServiceProvider + Clone> Ros for T {}