Skip to main content

cu_serial/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2
3//! Bounded, nonblocking byte I/O. UART writes can accept a prefix; callers own
4//! the remaining bytes. Zero means no progress, never EOF. Disconnection is an error.
5use embedded_io::{ErrorType, Read, ReadReady, Write, WriteReady};
6
7pub trait SerialIo: ErrorType {
8    /// Read once without waiting, locking, allocating or retrying.
9    fn try_read(&mut self, bytes: &mut [u8]) -> Result<usize, Self::Error>;
10    /// Write once without waiting, locking, allocating or retrying.
11    /// `Ok(n)` accepts exactly the first `n <= bytes.len()` bytes; `Err` accepts none.
12    fn try_write(&mut self, bytes: &[u8]) -> Result<usize, Self::Error>;
13}
14
15/// Adapt a HAL implementing the embedded-io readiness guarantees.
16#[derive(Debug)]
17pub struct ReadySerial<S>(pub S);
18
19impl<S: ErrorType> ErrorType for ReadySerial<S> {
20    type Error = S::Error;
21}
22
23impl<S: Read + ReadReady + Write + WriteReady> SerialIo for ReadySerial<S> {
24    fn try_read(&mut self, bytes: &mut [u8]) -> Result<usize, Self::Error> {
25        if bytes.is_empty() || !self.0.read_ready()? {
26            return Ok(0);
27        }
28        self.0.read(bytes)
29    }
30    fn try_write(&mut self, bytes: &[u8]) -> Result<usize, Self::Error> {
31        if bytes.is_empty() || !self.0.write_ready()? {
32            return Ok(0);
33        }
34        self.0.write(bytes)
35    }
36}