use crate::private;
pub trait AddressMode: private::Sealed {}
pub type SevenBitAddress = u8;
pub type TenBitAddress = u16;
impl AddressMode for SevenBitAddress {}
impl AddressMode for TenBitAddress {}
pub trait Read<A: AddressMode = SevenBitAddress> {
type Error;
fn try_read(&mut self, address: A, buffer: &mut [u8]) -> Result<(), Self::Error>;
}
pub trait Write<A: AddressMode = SevenBitAddress> {
type Error;
fn try_write(&mut self, address: A, bytes: &[u8]) -> Result<(), Self::Error>;
}
pub trait WriteIter<A: AddressMode = SevenBitAddress> {
type Error;
fn try_write_iter<B>(&mut self, address: A, bytes: B) -> Result<(), Self::Error>
where
B: IntoIterator<Item = u8>;
}
pub trait WriteRead<A: AddressMode = SevenBitAddress> {
type Error;
fn try_write_read(
&mut self,
address: A,
bytes: &[u8],
buffer: &mut [u8],
) -> Result<(), Self::Error>;
}
pub trait WriteIterRead<A: AddressMode = SevenBitAddress> {
type Error;
fn try_write_iter_read<B>(
&mut self,
address: A,
bytes: B,
buffer: &mut [u8],
) -> Result<(), Self::Error>
where
B: IntoIterator<Item = u8>;
}
#[derive(Debug, PartialEq)]
pub enum Operation<'a> {
Read(&'a mut [u8]),
Write(&'a [u8]),
}
pub trait Transactional<A: AddressMode = SevenBitAddress> {
type Error;
fn try_exec<'a>(
&mut self,
address: A,
operations: &mut [Operation<'a>],
) -> Result<(), Self::Error>;
}
pub trait TransactionalIter<A: AddressMode = SevenBitAddress> {
type Error;
fn try_exec_iter<'a, O>(&mut self, address: A, operations: O) -> Result<(), Self::Error>
where
O: IntoIterator<Item = Operation<'a>>;
}
pub mod transactional {
use super::{AddressMode, Operation, Read, Transactional, Write, WriteRead};
pub trait Default<A: AddressMode>: Transactional<A> {}
impl<A, E, S> Write<A> for S
where
A: AddressMode,
S: self::Default<A> + Transactional<A, Error = E>,
{
type Error = E;
fn try_write(&mut self, address: A, bytes: &[u8]) -> Result<(), Self::Error> {
self.try_exec(address, &mut [Operation::Write(bytes)])
}
}
impl<A, E, S> Read<A> for S
where
A: AddressMode,
S: self::Default<A> + Transactional<A, Error = E>,
{
type Error = E;
fn try_read(&mut self, address: A, buffer: &mut [u8]) -> Result<(), Self::Error> {
self.try_exec(address, &mut [Operation::Read(buffer)])
}
}
impl<A, E, S> WriteRead<A> for S
where
A: AddressMode,
S: self::Default<A> + Transactional<A, Error = E>,
{
type Error = E;
fn try_write_read(
&mut self,
address: A,
bytes: &[u8],
buffer: &mut [u8],
) -> Result<(), Self::Error> {
self.try_exec(
address,
&mut [Operation::Write(bytes), Operation::Read(buffer)],
)
}
}
}