async_hal/serial/
writer.rs

1use core::{
2    pin::Pin,
3    task::{Context, Poll},
4};
5use embedded_hal::serial::Write;
6use futures::Sink;
7
8/// Write half of a UART serial port.
9pub struct Writer<T, W> {
10    // Generic non-blocking serial writer
11    write: T,
12
13    // Cache of the next word to send
14    word: Option<W>,
15}
16
17impl<T, W> Writer<T, W> {
18    /// Create a new writer from an instance of [`Write`] and [`Scheduler`].
19    pub const fn new(transmit: T) -> Self {
20        Self {
21            write: transmit,
22            word: None,
23        }
24    }
25}
26
27impl<T, W> Sink<W> for Writer<T, W>
28where
29    T: Write<W> + Unpin,
30    W: Clone + Unpin,
31{
32    type Error = T::Error;
33
34    fn poll_ready(self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Result<(), Self::Error>> {
35        if self.word.is_none() {
36            Poll::Ready(Ok(()))
37        } else {
38            Poll::Pending
39        }
40    }
41
42    fn start_send(mut self: Pin<&mut Self>, item: W) -> Result<(), Self::Error> {
43        if self.word.is_none() {
44            self.word = Some(item);
45            Ok(())
46        } else {
47            todo!()
48        }
49    }
50
51    fn poll_flush(mut self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Result<(), Self::Error>> {
52        let Self { write, word } = &mut *self;
53
54        if let Some(word) = word.clone() {
55            // TODO flush!
56            match write.write(word) {
57                Ok(()) => {
58                    self.word = None;
59                    Poll::Ready(Ok(()))
60                }
61                Err(nb::Error::WouldBlock) => Poll::Pending,
62                Err(nb::Error::Other(error)) => Poll::Ready(Err(error)),
63            }
64        } else {
65            Poll::Ready(Ok(()))
66        }
67    }
68
69    fn poll_close(self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Result<(), Self::Error>> {
70        Poll::Ready(Ok(()))
71    }
72}