#![no_std]
#![deny(missing_docs)]
extern crate alloc;
extern crate fallible_collections;
extern crate heapless;
extern crate canadensis_core;
extern crate canadensis_encoding;
pub mod core {
pub use canadensis_core::*;
}
pub mod encoding {
pub use canadensis_encoding::*;
}
pub use canadensis_core::nb;
pub mod anonymous;
pub mod node;
mod publisher;
pub mod register;
pub mod requester;
mod serialize;
pub mod service;
use ::core::fmt::{Debug, Formatter};
use ::core::marker::PhantomData;
use alloc::vec::Vec;
use canadensis_core::{OutOfMemoryError, ServiceSubscribeError};
use crate::core::transport::Transport;
use canadensis_core::time::{Clock, MicrosecondDuration32};
use canadensis_core::transfer::*;
use canadensis_core::transport::{Receiver, Transmitter};
use canadensis_core::{ServiceId, SubjectId};
use canadensis_encoding::{Message, Request, Response, Serialize};
pub struct ResponseToken<T: Transport> {
service: ServiceId,
client: T::NodeId,
transfer: T::TransferId,
priority: T::Priority,
}
impl<T: Transport> Clone for ResponseToken<T>
where
T::NodeId: Clone,
T::TransferId: Clone,
T::Priority: Clone,
{
fn clone(&self) -> Self {
ResponseToken {
service: self.service,
client: self.client.clone(),
transfer: self.transfer.clone(),
priority: self.priority.clone(),
}
}
}
impl<T: Transport> Debug for ResponseToken<T>
where
T::NodeId: Debug,
T::TransferId: Debug,
T::Priority: Debug,
{
fn fmt(&self, f: &mut Formatter<'_>) -> ::core::fmt::Result {
f.debug_struct("ResponseToken")
.field("service", &self.service)
.field("client", &self.client)
.field("transfer", &self.transfer)
.field("priority", &self.priority)
.finish()
}
}
#[cfg(feature = "defmt")]
impl<T: Transport> defmt::Format for ResponseToken<T>
where
T::NodeId: defmt::Format,
T::TransferId: defmt::Format,
T::Priority: defmt::Format,
{
fn format(&self, f: defmt::Formatter) {
defmt::write!(
f,
"ResponseToken {{ service: {}, client: {}, transfer: {}, priority: {} }}",
self.service,
self.client,
self.transfer,
self.priority
)
}
}
pub trait TransferHandler<T: Transport> {
fn handle_message<N: Node<Transport = T>>(
&mut self,
_node: &mut N,
_transfer: &MessageTransfer<Vec<u8>, T>,
) -> bool {
false
}
fn handle_request<N: Node<Transport = T>>(
&mut self,
_node: &mut N,
_token: ResponseToken<T>,
_transfer: &ServiceTransfer<Vec<u8>, T>,
) -> bool {
false
}
fn handle_response<N: Node<Transport = T>>(
&mut self,
_node: &mut N,
_transfer: &ServiceTransfer<Vec<u8>, T>,
) -> bool {
false
}
fn handle_loopback<N: Node<Transport = T>>(
&mut self,
_node: &mut N,
_transfer: &Transfer<Vec<u8>, T>,
) -> bool {
false
}
fn chain<H>(self, next: H) -> TransferHandlerChain<Self, H>
where
Self: Sized,
H: TransferHandler<T>,
{
TransferHandlerChain::new(self, next)
}
}
impl<T, H> TransferHandler<T> for &mut H
where
T: Transport,
H: TransferHandler<T>,
{
fn handle_message<N: Node<Transport = T>>(
&mut self,
node: &mut N,
transfer: &MessageTransfer<Vec<u8>, T>,
) -> bool {
<H as TransferHandler<T>>::handle_message(self, node, transfer)
}
fn handle_request<N: Node<Transport = T>>(
&mut self,
node: &mut N,
token: ResponseToken<T>,
transfer: &ServiceTransfer<Vec<u8>, T>,
) -> bool {
<H as TransferHandler<T>>::handle_request(self, node, token, transfer)
}
fn handle_response<N: Node<Transport = T>>(
&mut self,
node: &mut N,
transfer: &ServiceTransfer<Vec<u8>, T>,
) -> bool {
<H as TransferHandler<T>>::handle_response(self, node, transfer)
}
fn handle_loopback<N: Node<Transport = T>>(
&mut self,
node: &mut N,
transfer: &Transfer<Vec<u8>, T>,
) -> bool {
<H as TransferHandler<T>>::handle_loopback(self, node, transfer)
}
fn chain<H1>(self, next: H1) -> TransferHandlerChain<Self, H1>
where
Self: Sized,
H1: TransferHandler<T>,
{
TransferHandlerChain::new(self, next)
}
}
pub struct TransferHandlerChain<H0, H1> {
handler0: H0,
handler1: H1,
}
impl<H0, H1> TransferHandlerChain<H0, H1> {
pub fn new(handler0: H0, handler1: H1) -> Self {
TransferHandlerChain { handler0, handler1 }
}
pub fn first(&self) -> &H0 {
&self.handler0
}
pub fn first_mut(&mut self) -> &mut H0 {
&mut self.handler0
}
pub fn second(&self) -> &H1 {
&self.handler1
}
pub fn second_mut(&mut self) -> &mut H1 {
&mut self.handler1
}
pub fn into_inner(self) -> (H0, H1) {
(self.handler0, self.handler1)
}
}
impl<T, H0, H1> TransferHandler<T> for TransferHandlerChain<H0, H1>
where
T: Transport,
H0: TransferHandler<T>,
H1: TransferHandler<T>,
{
fn handle_message<N: Node<Transport = T>>(
&mut self,
node: &mut N,
transfer: &MessageTransfer<Vec<u8>, T>,
) -> bool {
let handled = self.handler0.handle_message(node, transfer);
if handled {
true
} else {
self.handler1.handle_message(node, transfer)
}
}
fn handle_request<N: Node<Transport = T>>(
&mut self,
node: &mut N,
token: ResponseToken<T>,
transfer: &ServiceTransfer<Vec<u8>, T>,
) -> bool {
let handled = self.handler0.handle_request(node, token.clone(), transfer);
if handled {
true
} else {
self.handler1.handle_request(node, token, transfer)
}
}
fn handle_response<N: Node<Transport = T>>(
&mut self,
node: &mut N,
transfer: &ServiceTransfer<Vec<u8>, T>,
) -> bool {
let handled = self.handler0.handle_response(node, transfer);
if handled {
true
} else {
self.handler1.handle_response(node, transfer)
}
}
fn handle_loopback<N: Node<Transport = T>>(
&mut self,
node: &mut N,
transfer: &Transfer<Vec<u8>, T>,
) -> bool {
let handled = self.handler0.handle_loopback(node, transfer);
if handled {
true
} else {
self.handler1.handle_loopback(node, transfer)
}
}
}
pub trait Node {
type Clock: Clock;
type Transport: Transport;
type Transmitter: Transmitter<Self::Clock, Transport = Self::Transport>;
type Receiver: Receiver<Self::Clock, Transport = Self::Transport>;
fn receive<H>(
&mut self,
handler: &mut H,
) -> Result<(), <Self::Receiver as Receiver<Self::Clock>>::Error>
where
H: TransferHandler<Self::Transport>;
fn start_publishing(
&mut self,
subject: SubjectId,
timeout: MicrosecondDuration32,
priority: <Self::Transport as Transport>::Priority,
) -> Result<(), StartSendError<<Self::Transmitter as Transmitter<Self::Clock>>::Error>>;
fn stop_publishing(&mut self, subject: SubjectId);
fn publish<T>(
&mut self,
subject: SubjectId,
payload: &T,
) -> nb::Result<(), PublishError<<Self::Transmitter as Transmitter<Self::Clock>>::Error>>
where
T: Message + Serialize;
fn publish_loopback<T>(
&mut self,
subject: SubjectId,
payload: &T,
) -> nb::Result<(), PublishError<<Self::Transmitter as Transmitter<Self::Clock>>::Error>>
where
T: Message + Serialize;
fn start_sending_requests<T>(
&mut self,
service: ServiceId,
receive_timeout: MicrosecondDuration32,
response_payload_size_max: usize,
priority: <Self::Transport as Transport>::Priority,
) -> Result<ServiceToken<T>, StartSendError<<Self::Receiver as Receiver<Self::Clock>>::Error>>
where
T: Request;
fn stop_sending_requests<T>(&mut self, token: ServiceToken<T>)
where
T: Request;
fn send_request<T>(
&mut self,
token: &ServiceToken<T>,
payload: &T,
destination: <Self::Transport as Transport>::NodeId,
) -> nb::Result<
<Self::Transport as Transport>::TransferId,
<Self::Transmitter as Transmitter<Self::Clock>>::Error,
>
where
T: Request + Serialize;
fn send_request_loopback<T>(
&mut self,
token: &ServiceToken<T>,
payload: &T,
destination: <Self::Transport as Transport>::NodeId,
) -> nb::Result<
<Self::Transport as Transport>::TransferId,
<Self::Transmitter as Transmitter<Self::Clock>>::Error,
>
where
T: Request + Serialize;
fn subscribe_message(
&mut self,
subject: SubjectId,
payload_size_max: usize,
timeout: MicrosecondDuration32,
) -> Result<(), <Self::Receiver as Receiver<Self::Clock>>::Error>;
fn unsubscribe_message(&mut self, subject: SubjectId);
fn subscribe_request(
&mut self,
service: ServiceId,
payload_size_max: usize,
timeout: MicrosecondDuration32,
) -> Result<(), ServiceSubscribeError<<Self::Receiver as Receiver<Self::Clock>>::Error>>;
fn unsubscribe_request(&mut self, service: ServiceId);
fn send_response<T>(
&mut self,
token: ResponseToken<Self::Transport>,
timeout: MicrosecondDuration32,
payload: &T,
) -> nb::Result<(), <Self::Transmitter as Transmitter<Self::Clock>>::Error>
where
T: Response + Serialize;
fn flush(&mut self) -> nb::Result<(), <Self::Transmitter as Transmitter<Self::Clock>>::Error>;
fn clock(&self) -> &Self::Clock;
fn clock_mut(&mut self) -> &mut Self::Clock;
fn transmitter(&self) -> &Self::Transmitter;
fn transmitter_mut(&mut self) -> &mut Self::Transmitter;
fn receiver(&self) -> &Self::Receiver;
fn receiver_mut(&mut self) -> &mut Self::Receiver;
fn node_id(&self) -> Option<<Self::Transport as Transport>::NodeId>;
fn set_node_id(&mut self, node_id: <Self::Transport as Transport>::NodeId);
fn publishers(&self) -> impl Iterator<Item = SubjectId>;
fn subscribers(&self) -> impl Iterator<Item = SubjectId>;
fn clients(&self) -> impl Iterator<Item = ServiceId>;
fn servers(&self) -> impl Iterator<Item = ServiceId>;
}
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum PublishError<T> {
NotPublishing,
Transport(T),
}
pub struct ServiceToken<T>(ServiceId, PhantomData<T>);
impl<T> ServiceToken<T> {
pub fn service_id(&self) -> ServiceId {
self.0
}
}
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum StartSendError<E> {
Memory(OutOfMemoryError),
Transport(E),
Duplicate,
AnonymousRequest,
}
impl<E> From<E> for StartSendError<E> {
fn from(inner: E) -> Self {
StartSendError::Transport(inner)
}
}