bus/read.rs: Improve template code somewhat
This commit is contained in:
parent
e9f8d917a4
commit
59ba8ac20b
@ -10,7 +10,7 @@ use std::{fmt::Debug, slice::SliceIndex};
|
|||||||
/// Gets a `&[T]` at [SliceIndex] `I`.
|
/// Gets a `&[T]` at [SliceIndex] `I`.
|
||||||
///
|
///
|
||||||
/// This is similar to the [SliceIndex] method `.get(...)`, however implementing this trait
|
/// This is similar to the [SliceIndex] method `.get(...)`, however implementing this trait
|
||||||
/// for [u8] will auto-impl [Read]<(i8, u8, i16, u16 ... i128, u128)>
|
/// for [u8] will auto-impl [ReadWrite]<([i8], [u8], [i16], [u16] ... [i128], [u128])>
|
||||||
pub trait Get<T> {
|
pub trait Get<T> {
|
||||||
/// Gets the slice of Self at [SliceIndex] I
|
/// Gets the slice of Self at [SliceIndex] I
|
||||||
fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>
|
fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>
|
||||||
@ -23,7 +23,7 @@ pub trait Get<T> {
|
|||||||
I: SliceIndex<[T]>;
|
I: SliceIndex<[T]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read a T from address `addr`
|
/// Read or Write a T at address `addr`
|
||||||
pub trait ReadWrite<T>: FallibleReadWrite<T> {
|
pub trait ReadWrite<T>: FallibleReadWrite<T> {
|
||||||
/// Reads a T from address `addr`
|
/// Reads a T from address `addr`
|
||||||
///
|
///
|
||||||
@ -42,7 +42,7 @@ pub trait ReadWrite<T>: FallibleReadWrite<T> {
|
|||||||
|
|
||||||
/// Read a T from address `addr`, and return the value as a [Result]
|
/// Read a T from address `addr`, and return the value as a [Result]
|
||||||
pub trait FallibleReadWrite<T>: Get<u8> {
|
pub trait FallibleReadWrite<T>: Get<u8> {
|
||||||
/// The [Err] type returned by [read_fallible]
|
/// The [Err] type
|
||||||
type Error: Debug;
|
type Error: Debug;
|
||||||
/// Read a T from address `addr`, returning the value as a [Result]
|
/// Read a T from address `addr`, returning the value as a [Result]
|
||||||
fn read_fallible(&self, addr: impl Into<usize>) -> Result<T, Self::Error>;
|
fn read_fallible(&self, addr: impl Into<usize>) -> Result<T, Self::Error>;
|
||||||
@ -55,9 +55,9 @@ pub trait FallibleReadWrite<T>: Get<u8> {
|
|||||||
/// Relies on inherent methods of Rust numeric types:
|
/// Relies on inherent methods of Rust numeric types:
|
||||||
/// - `Self::from_be_bytes`
|
/// - `Self::from_be_bytes`
|
||||||
/// - `Self::to_be_bytes`
|
/// - `Self::to_be_bytes`
|
||||||
macro_rules! impl_rw {
|
macro_rules! impl_rw {($($t:ty) ,* $(,)?) =>{
|
||||||
($($t:ty) ,* $(,)?) => {
|
|
||||||
$(
|
$(
|
||||||
|
#[doc = concat!("Read or Write [", stringify!($t), "] at address `addr`")]
|
||||||
impl<T: Get<u8> + FallibleReadWrite<$t>> ReadWrite<$t> for T {
|
impl<T: Get<u8> + FallibleReadWrite<$t>> ReadWrite<$t> for T {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn read(&self, addr: impl Into<usize>) -> $t {
|
fn read(&self, addr: impl Into<usize>) -> $t {
|
||||||
@ -78,7 +78,7 @@ macro_rules! impl_rw {
|
|||||||
// Chip-8 is a big-endian system
|
// Chip-8 is a big-endian system
|
||||||
Ok(<$t>::from_be_bytes(bytes.try_into()?))
|
Ok(<$t>::from_be_bytes(bytes.try_into()?))
|
||||||
} else {
|
} else {
|
||||||
Err($crate::error::Error::InvalidAddressRange{range})
|
Err($crate::error::Error::InvalidAddressRange{range: range.into()})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@ -92,8 +92,7 @@ macro_rules! impl_rw {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
)*
|
)*
|
||||||
};
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
impl_rw!(i8, i16, i32, i64, i128);
|
impl_rw!(i8, i16, i32, i64, i128);
|
||||||
impl_rw!(u8, u16, u32, u64, u128);
|
impl_rw!(u8, u16, u32, u64, u128);
|
||||||
|
Loading…
Reference in New Issue
Block a user