async_hal/can/transmit/
transmitter.rs

1use super::Transmit;
2use core::{
3    pin::Pin,
4    task::{Context, Poll},
5};
6use futures::Sink;
7
8/// Transmitter sink for frames to a CAN bus.
9pub struct Transmitter<T, F> {
10    pub transmit: T,
11    frame: Option<F>,
12}
13
14impl<T, F> Transmitter<T, F> {
15    pub const fn new(transmit: T) -> Self {
16        Self {
17            transmit,
18            frame: None,
19        }
20    }
21}
22
23impl<T> Sink<T::Frame> for Transmitter<T, T::Frame>
24where
25    T: Transmit + Unpin,
26    T::Frame: Unpin,
27{
28    type Error = T::Error;
29
30    fn poll_ready(mut self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Result<(), Self::Error>> {
31        if self.transmit.is_ready() {
32            Poll::Ready(Ok(()))
33        } else {
34            Poll::Pending
35        }
36    }
37
38    fn start_send(mut self: Pin<&mut Self>, item: T::Frame) -> Result<(), Self::Error> {
39        if self.frame.is_none() {
40            self.frame = Some(item);
41            Ok(())
42        } else {
43            todo!()
44        }
45    }
46
47    fn poll_flush(mut self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Result<(), Self::Error>> {
48        let Self { transmit, frame } = &mut *self;
49
50        if let Some(ref frame) = frame {
51            match transmit.transmit(frame) {
52                Ok(()) => {
53                    self.frame = None;
54                    Poll::Ready(Ok(()))
55                }
56                Err(nb::Error::WouldBlock) => Poll::Pending,
57                Err(nb::Error::Other(error)) => Poll::Ready(Err(error)),
58            }
59        } else {
60            Poll::Ready(Ok(()))
61        }
62    }
63
64    fn poll_close(self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Result<(), Self::Error>> {
65        Poll::Ready(Ok(()))
66    }
67}