use crate::time::Microseconds32;
use crate::transport::Transport;
use crate::{PortId, ServiceId, SubjectId};
use core::fmt::{Debug, Formatter};
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct MessageHeader<T: Transport + ?Sized> {
pub timestamp: Microseconds32,
pub transfer_id: T::TransferId,
pub priority: T::Priority,
pub subject: SubjectId,
pub source: Option<T::NodeId>,
}
impl<T: Transport + ?Sized> Debug for MessageHeader<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.debug_struct("MessageHeader")
.field("timestamp", &self.timestamp)
.field("transfer_id", &self.transfer_id)
.field("priority", &self.priority)
.field("subject", &self.subject)
.field("source", &self.source)
.finish()
}
}
impl<T: Transport + ?Sized> Clone for MessageHeader<T>
where
T::TransferId: Clone,
T::Priority: Clone,
T::NodeId: Clone,
{
fn clone(&self) -> Self {
MessageHeader {
timestamp: self.timestamp,
transfer_id: self.transfer_id.clone(),
priority: self.priority.clone(),
subject: self.subject,
source: self.source.clone(),
}
}
}
impl<T: Transport + ?Sized> PartialEq for MessageHeader<T>
where
T::TransferId: PartialEq,
T::Priority: PartialEq,
T::NodeId: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.timestamp == other.timestamp
&& self.transfer_id == other.transfer_id
&& self.priority == other.priority
&& self.subject == other.subject
&& self.source == other.source
}
}
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct ServiceHeader<T: Transport + ?Sized> {
pub timestamp: Microseconds32,
pub transfer_id: T::TransferId,
pub priority: T::Priority,
pub service: ServiceId,
pub source: T::NodeId,
pub destination: T::NodeId,
}
impl<T: Transport + ?Sized> Debug for ServiceHeader<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.debug_struct("MessageHeader")
.field("timestamp", &self.timestamp)
.field("transfer_id", &self.transfer_id)
.field("priority", &self.priority)
.field("service", &self.service)
.field("source", &self.source)
.field("destination", &self.destination)
.finish()
}
}
impl<T: Transport + ?Sized> Clone for ServiceHeader<T>
where
T::TransferId: Clone,
T::Priority: Clone,
T::NodeId: Clone,
{
fn clone(&self) -> Self {
ServiceHeader {
timestamp: self.timestamp,
transfer_id: self.transfer_id.clone(),
priority: self.priority.clone(),
service: self.service,
source: self.source.clone(),
destination: self.destination.clone(),
}
}
}
impl<T: Transport + ?Sized> PartialEq for ServiceHeader<T>
where
T::TransferId: PartialEq,
T::Priority: PartialEq,
T::NodeId: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.timestamp == other.timestamp
&& self.transfer_id == other.transfer_id
&& self.priority == other.priority
&& self.service == other.service
&& self.source == other.source
&& self.destination == other.destination
}
}
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Header<T: Transport + ?Sized> {
Message(MessageHeader<T>),
Request(ServiceHeader<T>),
Response(ServiceHeader<T>),
}
impl<T: Transport + ?Sized> Debug for Header<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
match self {
Header::Message(inner) => f.debug_tuple("Message").field(inner).finish(),
Header::Request(inner) => f.debug_tuple("Request").field(inner).finish(),
Header::Response(inner) => f.debug_tuple("Response").field(inner).finish(),
}
}
}
impl<T: Transport + ?Sized> Clone for Header<T>
where
T::TransferId: Clone,
T::Priority: Clone,
T::NodeId: Clone,
{
fn clone(&self) -> Self {
match self {
Header::Message(inner) => Header::Message(inner.clone()),
Header::Request(inner) => Header::Request(inner.clone()),
Header::Response(inner) => Header::Response(inner.clone()),
}
}
}
impl<T: Transport + ?Sized> PartialEq for Header<T>
where
T::TransferId: PartialEq,
T::Priority: PartialEq,
T::NodeId: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Header::Message(lhs), Header::Message(rhs)) => lhs == rhs,
(Header::Request(lhs), Header::Request(rhs)) => lhs == rhs,
(Header::Response(lhs), Header::Response(rhs)) => lhs == rhs,
_ => false,
}
}
}
impl<T: Transport + ?Sized> Header<T> {
pub fn timestamp(&self) -> Microseconds32 {
match self {
Header::Message(ref message_header) => message_header.timestamp,
Header::Request(ref service_header) | Header::Response(ref service_header) => {
service_header.timestamp
}
}
}
pub fn set_timestamp(&mut self, timestamp: Microseconds32) {
match self {
Header::Message(ref mut message_header) => {
message_header.timestamp = timestamp;
}
Header::Request(ref mut transfer_header)
| Header::Response(ref mut transfer_header) => {
transfer_header.timestamp = timestamp;
}
}
}
pub fn priority(&self) -> &T::Priority {
match self {
Header::Message(ref message_header) => &message_header.priority,
Header::Request(ref service_header) | Header::Response(ref service_header) => {
&service_header.priority
}
}
}
pub fn set_priority(&mut self, priority: T::Priority) {
match self {
Header::Message(ref mut message_header) => {
message_header.priority = priority;
}
Header::Request(ref mut transfer_header)
| Header::Response(ref mut transfer_header) => {
transfer_header.priority = priority;
}
}
}
pub fn source(&self) -> Option<&T::NodeId> {
match self {
Header::Message(ref message_header) => message_header.source.as_ref(),
Header::Request(ref service_header) | Header::Response(ref service_header) => {
Some(&service_header.source)
}
}
}
pub fn port_id(&self) -> PortId {
match self {
Header::Message(ref message_header) => message_header.subject.into(),
Header::Request(ref service_header) | Header::Response(ref service_header) => {
service_header.service.into()
}
}
}
pub fn transfer_id(&self) -> &T::TransferId {
match self {
Header::Message(ref message_header) => &message_header.transfer_id,
Header::Request(ref service_header) | Header::Response(ref service_header) => {
&service_header.transfer_id
}
}
}
}
pub struct Transfer<A, T: Transport + ?Sized> {
pub header: Header<T>,
pub loopback: bool,
pub payload: A,
}
impl<A, T: Transport + ?Sized> Debug for Transfer<A, T>
where
A: Debug,
{
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Transfer")
.field("header", &self.header)
.field("loopback", &self.loopback)
.field("payload", &self.payload)
.finish()
}
}
#[cfg(feature = "defmt")]
impl<A, T: Transport + ?Sized> defmt::Format for Transfer<A, T>
where
A: defmt::Format,
<T as Transport>::NodeId: defmt::Format,
<T as Transport>::Priority: defmt::Format,
<T as Transport>::TransferId: defmt::Format,
{
fn format(&self, f: defmt::Formatter) {
defmt::write!(
f,
"Transfer {{ header: {}, loopback: {}, payload: {} }}",
self.header,
self.loopback,
self.payload
)
}
}
impl<A, T: Transport + ?Sized> PartialEq for Transfer<A, T>
where
A: PartialEq,
T::TransferId: PartialEq,
T::Priority: PartialEq,
T::NodeId: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.header == other.header
&& self.loopback == other.loopback
&& self.payload == other.payload
}
}
impl<A, T: Transport + ?Sized> Clone for Transfer<A, T>
where
A: Clone,
T::TransferId: Clone,
T::Priority: Clone,
T::NodeId: Clone,
{
fn clone(&self) -> Self {
Transfer {
header: self.header.clone(),
loopback: self.loopback,
payload: self.payload.clone(),
}
}
}
#[derive(Clone)]
pub struct MessageTransfer<A, T: Transport + ?Sized> {
pub header: MessageHeader<T>,
pub loopback: bool,
pub payload: A,
}
impl<A, T: Transport + ?Sized> Debug for MessageTransfer<A, T>
where
A: Debug,
{
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Transfer")
.field("header", &self.header)
.field("loopback", &self.loopback)
.field("payload", &self.payload)
.finish()
}
}
#[cfg(feature = "defmt")]
impl<A, T: Transport + ?Sized> defmt::Format for MessageTransfer<A, T>
where
A: defmt::Format,
<T as Transport>::NodeId: defmt::Format,
<T as Transport>::Priority: defmt::Format,
<T as Transport>::TransferId: defmt::Format,
{
fn format(&self, f: defmt::Formatter) {
defmt::write!(
f,
"Transfer {{ header: {}, loopback: {}, payload: {} }}",
self.header,
self.loopback,
self.payload
)
}
}
impl<A, T: Transport + ?Sized> PartialEq for MessageTransfer<A, T>
where
A: PartialEq,
T::TransferId: PartialEq,
T::Priority: PartialEq,
T::NodeId: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.header == other.header
&& self.loopback == other.loopback
&& self.payload == other.payload
}
}
#[derive(Clone)]
pub struct ServiceTransfer<A, T: Transport + ?Sized> {
pub header: ServiceHeader<T>,
pub loopback: bool,
pub payload: A,
}
impl<A, T: Transport + ?Sized> Debug for ServiceTransfer<A, T>
where
A: Debug,
{
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Transfer")
.field("header", &self.header)
.field("loopback", &self.loopback)
.field("payload", &self.payload)
.finish()
}
}
#[cfg(feature = "defmt")]
impl<A, T: Transport + ?Sized> defmt::Format for ServiceTransfer<A, T>
where
A: defmt::Format,
<T as Transport>::NodeId: defmt::Format,
<T as Transport>::Priority: defmt::Format,
<T as Transport>::TransferId: defmt::Format,
{
fn format(&self, f: defmt::Formatter) {
defmt::write!(
f,
"Transfer {{ header: {}, loopback: {}, payload: {} }}",
self.header,
self.loopback,
self.payload
)
}
}
impl<A, T: Transport + ?Sized> PartialEq for ServiceTransfer<A, T>
where
A: PartialEq,
T::TransferId: PartialEq,
T::Priority: PartialEq,
T::NodeId: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.header == other.header
&& self.loopback == other.loopback
&& self.payload == other.payload
}
}