#![doc = include_str!("../README.md")]
#![no_std]
#![deny(unsafe_code, missing_docs)]
pub use device_register_macro::*;
pub trait Register {
type Address;
const ADDRESS: Self::Address;
}
pub trait ReadableRegister: Register {}
pub trait EditableRegister: Register {}
pub trait WritableRegister: Register {}
pub trait RegisterInterface<R, A>
where
R: Register<Address = A>,
{
type Error;
fn read_register(&mut self) -> Result<R, Self::Error>;
fn write_register(&mut self, register: &R) -> Result<(), Self::Error>;
}
pub trait ReadRegister<R, A>
where
R: ReadableRegister<Address = A>,
{
type Error;
fn read(&mut self) -> Result<R, Self::Error>;
}
pub trait WriteRegister<R, A>
where
R: WritableRegister<Address = A>,
{
type Error;
fn write(&mut self, register: R) -> Result<(), Self::Error>;
}
pub trait EditRegister<R, A>
where
R: EditableRegister<Address = A>,
{
type Error;
fn edit<F>(&mut self, f: F) -> Result<(), Self::Error>
where
for<'w> F: FnOnce(&'w mut R);
}
impl<I, R, A> ReadRegister<R, A> for I
where
R: ReadableRegister<Address = A>,
I: RegisterInterface<R, A>,
{
type Error = I::Error;
fn read(&mut self) -> Result<R, Self::Error> {
self.read_register()
}
}
impl<I, R, A> WriteRegister<R, A> for I
where
R: WritableRegister<Address = A>,
I: RegisterInterface<R, A>,
{
type Error = I::Error;
fn write(&mut self, register: R) -> Result<(), Self::Error> {
self.write_register(®ister)
}
}
impl<I, R, A> EditRegister<R, A> for I
where
R: EditableRegister<Address = A>,
I: RegisterInterface<R, A>,
{
type Error = I::Error;
fn edit<F>(&mut self, f: F) -> Result<(), Self::Error>
where
for<'w> F: FnOnce(&'w mut R),
{
let mut val = self.read_register()?;
f(&mut val);
self.write_register(&val)
}
}