use crate::{ReadCapability, WriteCapability};
use core::marker::PhantomData;
pub trait BufferInterfaceError {
type Error;
}
pub trait BufferInterface: BufferInterfaceError {
type AddressType: Copy;
fn write(&mut self, address: Self::AddressType, buf: &[u8]) -> Result<usize, Self::Error>;
fn flush(&mut self, address: Self::AddressType) -> Result<(), Self::Error>;
fn read(&mut self, address: Self::AddressType, buf: &mut [u8]) -> Result<usize, Self::Error>;
}
pub trait AsyncBufferInterface: BufferInterfaceError {
type AddressType: Copy;
async fn write(&mut self, address: Self::AddressType, buf: &[u8])
-> Result<usize, Self::Error>;
async fn flush(&mut self, address: Self::AddressType) -> Result<(), Self::Error>;
async fn read(
&mut self,
address: Self::AddressType,
buf: &mut [u8],
) -> Result<usize, Self::Error>;
}
pub struct BufferOperation<'i, Interface, AddressType: Copy, Access> {
interface: &'i mut Interface,
address: AddressType,
_phantom: PhantomData<Access>,
}
impl<'i, Interface, AddressType: Copy, Access> BufferOperation<'i, Interface, AddressType, Access> {
#[doc(hidden)]
pub fn new(interface: &'i mut Interface, address: AddressType) -> Self {
Self {
interface,
address,
_phantom: PhantomData,
}
}
}
impl<Interface, AddressType: Copy, Access> BufferOperation<'_, Interface, AddressType, Access>
where
Interface: BufferInterface<AddressType = AddressType>,
Access: WriteCapability,
{
pub fn write(&mut self, buf: &[u8]) -> Result<usize, Interface::Error> {
self.interface.write(self.address, buf)
}
pub fn write_all(&mut self, mut buf: &[u8]) -> Result<(), Interface::Error> {
while !buf.is_empty() {
match self.write(buf) {
Ok(0) => panic!("write() returned Ok(0)"),
Ok(n) => buf = &buf[n..],
Err(e) => return Err(e),
}
}
Ok(())
}
pub fn flush(&mut self) -> Result<(), Interface::Error> {
self.interface.flush(self.address)
}
}
impl<Interface, AddressType: Copy, Access> BufferOperation<'_, Interface, AddressType, Access>
where
Interface: BufferInterface<AddressType = AddressType>,
Access: ReadCapability,
{
pub fn read(&mut self, buf: &mut [u8]) -> Result<usize, Interface::Error> {
self.interface.read(self.address, buf)
}
pub fn read_exact(
&mut self,
mut buf: &mut [u8],
) -> Result<(), embedded_io::ReadExactError<Interface::Error>> {
while !buf.is_empty() {
match self.read(buf) {
Ok(0) => break,
Ok(n) => buf = &mut buf[n..],
Err(e) => return Err(embedded_io::ReadExactError::Other(e)),
}
}
if buf.is_empty() {
Ok(())
} else {
Err(embedded_io::ReadExactError::UnexpectedEof)
}
}
}
impl<Interface, AddressType: Copy, Access> BufferOperation<'_, Interface, AddressType, Access>
where
Interface: AsyncBufferInterface<AddressType = AddressType>,
Access: WriteCapability,
{
pub async fn write_async(&mut self, buf: &[u8]) -> Result<usize, Interface::Error> {
self.interface.write(self.address, buf).await
}
pub async fn write_all_async(&mut self, mut buf: &[u8]) -> Result<(), Interface::Error> {
while !buf.is_empty() {
match self.write_async(buf).await {
Ok(0) => panic!("write() returned Ok(0)"),
Ok(n) => buf = &buf[n..],
Err(e) => return Err(e),
}
}
Ok(())
}
pub async fn flush_async(&mut self) -> Result<(), Interface::Error> {
self.interface.flush(self.address).await
}
}
impl<Interface, AddressType: Copy, Access> BufferOperation<'_, Interface, AddressType, Access>
where
Interface: AsyncBufferInterface<AddressType = AddressType>,
Access: ReadCapability,
{
pub async fn read_async(&mut self, buf: &mut [u8]) -> Result<usize, Interface::Error> {
self.interface.read(self.address, buf).await
}
pub async fn read_exact_async(
&mut self,
mut buf: &mut [u8],
) -> Result<(), embedded_io::ReadExactError<Interface::Error>> {
while !buf.is_empty() {
match self.read_async(buf).await {
Ok(0) => break,
Ok(n) => buf = &mut buf[n..],
Err(e) => return Err(embedded_io::ReadExactError::Other(e)),
}
}
if buf.is_empty() {
Ok(())
} else {
Err(embedded_io::ReadExactError::UnexpectedEof)
}
}
}
impl<Interface, AddressType: Copy, Access> embedded_io::ErrorType
for BufferOperation<'_, Interface, AddressType, Access>
where
Interface: BufferInterfaceError,
Interface::Error: embedded_io::Error,
{
type Error = Interface::Error;
}
impl<Interface, AddressType: Copy, Access> embedded_io::Write
for BufferOperation<'_, Interface, AddressType, Access>
where
Interface: BufferInterface<AddressType = AddressType>,
Interface::Error: embedded_io::Error,
Access: WriteCapability,
{
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
self.write(buf)
}
fn flush(&mut self) -> Result<(), Self::Error> {
self.flush()
}
}
impl<Interface, AddressType: Copy, Access> embedded_io::Read
for BufferOperation<'_, Interface, AddressType, Access>
where
Interface: BufferInterface<AddressType = AddressType>,
Interface::Error: embedded_io::Error,
Access: ReadCapability,
{
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
self.read(buf)
}
}
impl<Interface, AddressType: Copy, Access> embedded_io_async::Write
for BufferOperation<'_, Interface, AddressType, Access>
where
Interface: AsyncBufferInterface<AddressType = AddressType>,
Interface::Error: embedded_io::Error,
Access: WriteCapability,
{
async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
self.write_async(buf).await
}
async fn flush(&mut self) -> Result<(), Self::Error> {
self.flush_async().await
}
}
impl<Interface, AddressType: Copy, Access> embedded_io_async::Read
for BufferOperation<'_, Interface, AddressType, Access>
where
Interface: AsyncBufferInterface<AddressType = AddressType>,
Interface::Error: embedded_io::Error,
Access: ReadCapability,
{
async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
self.read_async(buf).await
}
}