#![no_std]
#![deny(missing_docs, unaligned_references)]
extern crate alloc;
extern crate fallible_collections;
extern crate hash32;
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;
use ::core::fmt::{Debug, Formatter};
use ::core::marker::PhantomData;
use alloc::vec::Vec;
use canadensis_core::OutOfMemoryError;
use crate::core::transport::Transport;
use canadensis_core::time::{Clock, Instant};
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.clone(),
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()
}
}
pub trait TransferHandler<I: Instant, T: Transport> {
fn handle_message<N: Node<Instant = I, Transport = T>>(
&mut self,
node: &mut N,
transfer: &MessageTransfer<Vec<u8>, I, T>,
) -> bool {
drop((node, transfer));
false
}
fn handle_request<N: Node<Instant = I, Transport = T>>(
&mut self,
node: &mut N,
token: ResponseToken<T>,
transfer: &ServiceTransfer<Vec<u8>, I, T>,
) -> bool {
drop((node, token, transfer));
false
}
fn handle_response<N: Node<Instant = I, Transport = T>>(
&mut self,
node: &mut N,
transfer: &ServiceTransfer<Vec<u8>, I, T>,
) -> bool {
drop((node, transfer));
false
}
fn chain<H>(self, next: H) -> TransferHandlerChain<Self, H>
where
Self: Sized,
H: TransferHandler<I, T>,
{
TransferHandlerChain::new(self, next)
}
}
impl<'h, I, T, H> TransferHandler<I, T> for &'h mut H
where
I: Instant,
T: Transport,
H: TransferHandler<I, T>,
{
fn handle_message<N: Node<Instant = I, Transport = T>>(
&mut self,
node: &mut N,
transfer: &MessageTransfer<Vec<u8>, I, T>,
) -> bool {
<H as TransferHandler<I, T>>::handle_message(self, node, transfer)
}
fn handle_request<N: Node<Instant = I, Transport = T>>(
&mut self,
node: &mut N,
token: ResponseToken<T>,
transfer: &ServiceTransfer<Vec<u8>, I, T>,
) -> bool {
<H as TransferHandler<I, T>>::handle_request(self, node, token, transfer)
}
fn handle_response<N: Node<Instant = I, Transport = T>>(
&mut self,
node: &mut N,
transfer: &ServiceTransfer<Vec<u8>, I, T>,
) -> bool {
<H as TransferHandler<I, T>>::handle_response(self, node, transfer)
}
fn chain<H1>(self, next: H1) -> TransferHandlerChain<Self, H1>
where
Self: Sized,
H1: TransferHandler<I, 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<I, T, H0, H1> TransferHandler<I, T> for TransferHandlerChain<H0, H1>
where
I: Instant,
T: Transport,
H0: TransferHandler<I, T>,
H1: TransferHandler<I, T>,
{
fn handle_message<N: Node<Instant = I, Transport = T>>(
&mut self,
node: &mut N,
transfer: &MessageTransfer<Vec<u8>, I, 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<Instant = I, Transport = T>>(
&mut self,
node: &mut N,
token: ResponseToken<T>,
transfer: &ServiceTransfer<Vec<u8>, I, 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<Instant = I, Transport = T>>(
&mut self,
node: &mut N,
transfer: &ServiceTransfer<Vec<u8>, I, T>,
) -> bool {
let handled = self.handler0.handle_response(node, transfer);
if handled {
true
} else {
self.handler1.handle_response(node, transfer)
}
}
}
pub trait Node {
type Clock: Clock<Instant = Self::Instant>;
type Instant: Instant;
type Transport: Transport;
type Transmitter: Transmitter<Self::Instant, Transport = Self::Transport>;
type Receiver: Receiver<Self::Instant, Transport = Self::Transport>;
fn receive<H>(
&mut self,
handler: &mut H,
) -> Result<(), <Self::Receiver as Receiver<Self::Instant>>::Error>
where
H: TransferHandler<Self::Instant, Self::Transport>;
fn start_publishing<T>(
&mut self,
subject: SubjectId,
timeout: <<<Self as Node>::Clock as Clock>::Instant as Instant>::Duration,
priority: <Self::Transport as Transport>::Priority,
) -> Result<
PublishToken<T>,
StartSendError<<Self::Transmitter as Transmitter<Self::Instant>>::Error>,
>
where
T: Message;
fn stop_publishing<T>(&mut self, token: PublishToken<T>)
where
T: Message;
fn publish<T>(
&mut self,
token: &PublishToken<T>,
payload: &T,
) -> nb::Result<(), <Self::Transmitter as Transmitter<Self::Instant>>::Error>
where
T: Message + Serialize;
fn start_sending_requests<T>(
&mut self,
service: ServiceId,
receive_timeout: <<<Self as Node>::Clock as Clock>::Instant as Instant>::Duration,
response_payload_size_max: usize,
priority: <Self::Transport as Transport>::Priority,
) -> Result<ServiceToken<T>, StartSendError<<Self::Receiver as Receiver<Self::Instant>>::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::Instant>>::Error,
>
where
T: Request + Serialize;
fn subscribe_message(
&mut self,
subject: SubjectId,
payload_size_max: usize,
timeout: <<<Self as Node>::Clock as Clock>::Instant as Instant>::Duration,
) -> Result<(), <Self::Receiver as Receiver<Self::Instant>>::Error>;
fn subscribe_request(
&mut self,
service: ServiceId,
payload_size_max: usize,
timeout: <<<Self as Node>::Clock as Clock>::Instant as Instant>::Duration,
) -> Result<(), <Self::Receiver as Receiver<Self::Instant>>::Error>;
fn send_response<T>(
&mut self,
token: ResponseToken<Self::Transport>,
timeout: <<<Self as Node>::Clock as Clock>::Instant as Instant>::Duration,
payload: &T,
) -> nb::Result<(), <Self::Transmitter as Transmitter<Self::Instant>>::Error>
where
T: Response + Serialize;
fn flush(&mut self)
-> nb::Result<(), <Self::Transmitter as Transmitter<Self::Instant>>::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) -> <Self::Transport as Transport>::NodeId;
}
pub struct PublishToken<T>(SubjectId, PhantomData<T>);
impl<T> PublishToken<T> {
pub fn subject_id(&self) -> SubjectId {
self.0
}
}
mod fmt_impl {
use super::PublishToken;
use core::fmt::{Debug, Formatter, Result};
impl<T> Debug for PublishToken<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
f.debug_tuple("PublishToken").field(&self.0).finish()
}
}
}
pub struct ServiceToken<T>(ServiceId, PhantomData<T>);
impl<T> ServiceToken<T> {
pub fn service_id(&self) -> ServiceId {
self.0
}
}
#[derive(Debug)]
pub enum StartSendError<E> {
Memory(OutOfMemoryError),
Transport(E),
Duplicate,
}
impl<E> From<E> for StartSendError<E> {
fn from(inner: E) -> Self {
StartSendError::Transport(inner)
}
}