1use core::marker::PhantomData;
6
7use crate::serialize::do_serialize;
8use crate::Clock;
9use canadensis_core::time::{MicrosecondDuration32, Microseconds32};
10use canadensis_core::transfer::{Header, MessageHeader, Transfer};
11use canadensis_core::transport::{TransferId, Transmitter, Transport};
12use canadensis_core::{nb, SubjectId};
13use canadensis_encoding::{Message, Serialize};
14
15pub struct AnonymousPublisher<C: Clock, M, T: Transmitter<C>> {
21 priority: <T::Transport as Transport>::Priority,
23 subject: SubjectId,
25 next_transfer_id: <T::Transport as Transport>::TransferId,
27 timeout: MicrosecondDuration32,
29 _message_phantom: PhantomData<M>,
31}
32
33impl<C, M, T> AnonymousPublisher<C, M, T>
34where
35 C: Clock,
36 M: Message + Serialize,
37 T: Transmitter<C>,
38{
39 pub fn new(
41 subject: SubjectId,
42 priority: <T::Transport as Transport>::Priority,
43 timeout: MicrosecondDuration32,
44 ) -> Self {
45 AnonymousPublisher {
46 priority,
47 subject,
48 next_transfer_id: <T::Transport as Transport>::TransferId::default(),
49 timeout,
50 _message_phantom: PhantomData,
51 }
52 }
53
54 pub fn send(
59 &mut self,
60 payload: &M,
61 clock: &mut C,
62 transmitter: &mut T,
63 driver: &mut T::Driver,
64 ) -> nb::Result<(), AnonymousPublishError<T::Error>> {
65 self.send_inner(payload, false, clock, transmitter, driver)
66 }
67
68 pub fn send_loopback(
74 &mut self,
75 payload: &M,
76 clock: &mut C,
77 transmitter: &mut T,
78 driver: &mut T::Driver,
79 ) -> nb::Result<(), AnonymousPublishError<T::Error>> {
80 self.send_inner(payload, true, clock, transmitter, driver)
81 }
82
83 fn send_inner(
84 &mut self,
85 payload: &M,
86 loopback: bool,
87 clock: &mut C,
88 transmitter: &mut T,
89 driver: &mut T::Driver,
90 ) -> nb::Result<(), AnonymousPublishError<T::Error>> {
91 let payload_size_bytes = payload.size_bits().div_ceil(8);
93 if payload_size_bytes > transmitter.mtu() {
94 return Err(nb::Error::Other(AnonymousPublishError::Length));
95 }
96 let deadline = clock.now() + self.timeout;
98 do_serialize(payload, |payload_bytes| {
99 self.send_payload(
100 payload_bytes,
101 deadline,
102 loopback,
103 transmitter,
104 clock,
105 driver,
106 )
107 })
108 .map_err(|e| e.map(AnonymousPublishError::Transport))?;
109 Ok(())
110 }
111
112 fn send_payload(
113 &mut self,
114 payload: &[u8],
115 deadline: Microseconds32,
116 loopback: bool,
117 transmitter: &mut T,
118 clock: &mut C,
119 driver: &mut T::Driver,
120 ) -> nb::Result<(), T::Error> {
121 let transfer = Transfer {
123 header: Header::Message(MessageHeader {
124 timestamp: deadline,
125 transfer_id: self.next_transfer_id.clone(),
126 priority: self.priority.clone(),
127 subject: self.subject,
128 source: None,
129 }),
130 loopback,
131 payload,
132 };
133 self.next_transfer_id = self.next_transfer_id.clone().increment();
134
135 transmitter.push(transfer, clock, driver)
136 }
137}
138
139#[derive(Debug)]
141pub enum AnonymousPublishError<E> {
142 Length,
144 Transport(E),
146}
147
148impl<E> From<E> for AnonymousPublishError<E> {
149 fn from(inner: E) -> Self {
150 AnonymousPublishError::Transport(inner)
151 }
152}