mirror of
https://github.com/PSenfft/mb85rc.git
synced 2025-08-22 12:54:16 +00:00
implemented more functionality for embedded_io
This commit is contained in:
parent
54d35ebbec
commit
c6d7ca79d0
@ -6,12 +6,12 @@ use crate::{
|
|||||||
embedded_io::{error::MB85RCErrorType, head::Head},
|
embedded_io::{error::MB85RCErrorType, head::Head},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct EmbedIODev<T: I2c> {
|
pub struct EmbedIODev<T: I2c, const N: u64> {
|
||||||
dev: crate::MB85RC<T>,
|
dev: crate::MB85RC<T>,
|
||||||
head: Head,
|
head: Head<N>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: I2c> EmbedIODev<T> {
|
impl<T: I2c, const N: u64> EmbedIODev<T, N> {
|
||||||
pub fn new(mb85rc: MB85RC<T>) -> Self {
|
pub fn new(mb85rc: MB85RC<T>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
dev: mb85rc,
|
dev: mb85rc,
|
||||||
@ -20,42 +20,59 @@ impl<T: I2c> EmbedIODev<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: I2c> ErrorType for EmbedIODev<T> {
|
impl<T: I2c, const N: u64> ErrorType for EmbedIODev<T, N> {
|
||||||
type Error = MB85RCErrorType<T::Error>;
|
type Error = MB85RCErrorType<T::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: I2c> Read for EmbedIODev<T> {
|
impl<T: I2c, const N: u64> Read for EmbedIODev<T, N> {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
|
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
|
||||||
self.dev
|
match self.head.memory_address() {
|
||||||
.sequential_read(&self.head.memory_address().unwrap(), buf)
|
Some(addr) => self
|
||||||
.map_err(MB85RCErrorType::I2c)
|
.dev
|
||||||
.map(|_| {
|
.sequential_read(&addr, buf)
|
||||||
self.head.advance(buf.len());
|
.map_err(MB85RCErrorType::I2c)
|
||||||
buf.len()
|
.map(|_| {
|
||||||
})
|
self.head.advance(buf.len());
|
||||||
|
buf.len()
|
||||||
|
}),
|
||||||
|
None => Err(MB85RCErrorType::InvalidPosition),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: I2c> Write for EmbedIODev<T> {
|
impl<T: I2c, const N: u64> Write for EmbedIODev<T, N> {
|
||||||
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
|
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
|
||||||
// From trait doc: Implementations must not return Ok(0) unless buf is empty.
|
// From trait doc: Implementations must not return Ok(0) unless buf is empty.
|
||||||
if buf.is_empty() {
|
if buf.is_empty() {
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// match self.head.memory_address() {
|
||||||
|
// Some(addr) => self
|
||||||
|
// .dev
|
||||||
|
// .write_page(&addr, buf)
|
||||||
|
// .map_err(MB85RCErrorType::I2c)
|
||||||
|
// .map(|_| {
|
||||||
|
// self.head.advance(buf.len());
|
||||||
|
// buf.len()
|
||||||
|
// }),
|
||||||
|
// None => Err(MB85RCErrorType::InvalidPosition),
|
||||||
|
// }
|
||||||
|
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush(&mut self) -> Result<(), Self::Error> {
|
fn flush(&mut self) -> Result<(), Self::Error> {
|
||||||
todo!()
|
// We can't really flush here.
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: I2c> Seek for EmbedIODev<T> {
|
impl<T: I2c, const N: u64> Seek for EmbedIODev<T, N> {
|
||||||
fn seek(&mut self, pos: embedded_io::SeekFrom) -> Result<u64, Self::Error> {
|
fn seek(&mut self, pos: embedded_io::SeekFrom) -> Result<u64, Self::Error> {
|
||||||
self.head
|
self.head
|
||||||
.seek(pos)
|
.seek(pos)
|
||||||
.map_err(|_| MB85RCErrorType::InvalidPosition)?;
|
.ok_or(MB85RCErrorType::InvalidPosition)?;
|
||||||
Ok(self.head.into())
|
Ok(self.head.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,34 @@
|
|||||||
use embedded_io::SeekFrom;
|
use embedded_io::SeekFrom;
|
||||||
|
|
||||||
/// moveable Read/Write head
|
/// moveable Read/Write head
|
||||||
|
/// Capped at `N`
|
||||||
|
/// Does not allow overflow
|
||||||
#[derive(Clone, Copy, Default)]
|
#[derive(Clone, Copy, Default)]
|
||||||
pub struct Head(u64);
|
pub struct Head<const N: u64>(u64);
|
||||||
|
|
||||||
impl Head {
|
impl<const N: u64> Head<N> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self(0)
|
Self(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn seek(&mut self, pos: SeekFrom) -> Result<u64, ()> {
|
pub fn seek(&mut self, pos: SeekFrom) -> Option<u64> {
|
||||||
match pos {
|
match pos {
|
||||||
SeekFrom::Start(offset) => {
|
SeekFrom::Start(offset) => match self.0.checked_add(offset).filter(|&sum| sum <= N) {
|
||||||
self.0 = offset;
|
Some(new_pos) => {
|
||||||
Ok(self.0)
|
self.0 = new_pos;
|
||||||
}
|
Some(new_pos)
|
||||||
|
}
|
||||||
|
None => None,
|
||||||
|
},
|
||||||
SeekFrom::End(offset) => {
|
SeekFrom::End(offset) => {
|
||||||
|
// Do not allow seek over the end
|
||||||
if offset > 0 {
|
if offset > 0 {
|
||||||
return Err(());
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.0 = u64::MAX - offset.unsigned_abs();
|
self.0 = N - offset.unsigned_abs();
|
||||||
|
|
||||||
Ok(self.0)
|
Some(self.0)
|
||||||
}
|
}
|
||||||
SeekFrom::Current(offset) => {
|
SeekFrom::Current(offset) => {
|
||||||
let new_pos = if offset > 0 {
|
let new_pos = if offset > 0 {
|
||||||
@ -33,21 +39,31 @@ impl Head {
|
|||||||
|
|
||||||
match new_pos {
|
match new_pos {
|
||||||
Some(pos) => {
|
Some(pos) => {
|
||||||
self.0 = pos;
|
if pos > N {
|
||||||
Ok(self.0)
|
None
|
||||||
|
} else {
|
||||||
|
self.0 = pos;
|
||||||
|
Some(self.0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
None => Err(()),
|
None => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Move the head forward when reading files.
|
/// Move the head forward when reading files.
|
||||||
/// Expected to not overflow. If it does it is capped at `u64::MAX`.
|
/// Expected to not overflow. If it does it is capped at `N`.
|
||||||
pub fn advance(&mut self, bytes: usize) {
|
pub fn advance(&mut self, bytes: usize) {
|
||||||
match u64::try_from(bytes) {
|
match self.0.checked_add(bytes as u64) {
|
||||||
Ok(offset) => self.0 += offset,
|
Some(sum) => {
|
||||||
Err(_) => self.0 = u64::MAX,
|
if sum > N {
|
||||||
|
self.0 = N
|
||||||
|
} else {
|
||||||
|
self.0 = sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => self.0 = N,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,8 +81,8 @@ impl Head {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Head> for u64 {
|
impl<const N: u64> From<Head<N>> for u64 {
|
||||||
fn from(head: Head) -> Self {
|
fn from(head: Head<N>) -> Self {
|
||||||
head.0
|
head.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,87 +93,94 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn create() {
|
fn create() {
|
||||||
let head = Head::new();
|
let head: Head<65_535> = Head::new();
|
||||||
let inner: u64 = head.into();
|
let inner: u64 = head.into();
|
||||||
assert_eq!(inner, 0u64);
|
assert_eq!(inner, 0u64);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn seek_start() {
|
fn seek_start() {
|
||||||
let mut head = Head::new();
|
let mut head: Head<65_535> = Head::new();
|
||||||
let res = head.seek(SeekFrom::Start(1337));
|
let res = head.seek(SeekFrom::Start(1337));
|
||||||
|
|
||||||
let inner: u64 = head.into();
|
let inner: u64 = head.into();
|
||||||
assert_eq!(inner, 1337u64);
|
assert_eq!(inner, 1337u64);
|
||||||
assert_eq!(res, Ok(inner));
|
assert_eq!(res, Some(inner));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn seek_current_forward() {
|
fn seek_current_forward() {
|
||||||
let mut head = Head::new();
|
let mut head: Head<65_535> = Head::new();
|
||||||
let _ = head.seek(SeekFrom::Start(1337));
|
let _ = head.seek(SeekFrom::Start(1337));
|
||||||
|
|
||||||
let res = head.seek(SeekFrom::Current(3));
|
let res = head.seek(SeekFrom::Current(3));
|
||||||
|
|
||||||
let inner: u64 = head.into();
|
let inner: u64 = head.into();
|
||||||
assert_eq!(inner, 1340u64);
|
assert_eq!(inner, 1340u64);
|
||||||
assert_eq!(res, Ok(inner));
|
assert_eq!(res, Some(inner));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn seek_current_back() {
|
fn seek_current_back() {
|
||||||
let mut head = Head::new();
|
let mut head: Head<65_535> = Head::new();
|
||||||
let _ = head.seek(SeekFrom::Start(1337));
|
let _ = head.seek(SeekFrom::Start(1337));
|
||||||
|
|
||||||
let res = head.seek(SeekFrom::Current(-337));
|
let res = head.seek(SeekFrom::Current(-337));
|
||||||
|
|
||||||
let inner: u64 = head.into();
|
let inner: u64 = head.into();
|
||||||
assert_eq!(inner, 1000u64);
|
assert_eq!(inner, 1000u64);
|
||||||
assert_eq!(res, Ok(inner));
|
assert_eq!(res, Some(inner));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn seek_current_zero() {
|
fn seek_current_zero() {
|
||||||
let mut head = Head::new();
|
let mut head: Head<65_535> = Head::new();
|
||||||
let _ = head.seek(SeekFrom::Start(1337));
|
let _ = head.seek(SeekFrom::Start(1337));
|
||||||
|
|
||||||
let res = head.seek(SeekFrom::Current(0));
|
let res = head.seek(SeekFrom::Current(0));
|
||||||
|
|
||||||
let inner: u64 = head.into();
|
let inner: u64 = head.into();
|
||||||
assert_eq!(inner, 1337u64);
|
assert_eq!(inner, 1337u64);
|
||||||
assert_eq!(res, Ok(inner));
|
assert_eq!(res, Some(inner));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn seek_end() {
|
fn seek_end() {
|
||||||
let mut head = Head::new();
|
let mut head: Head<65_535> = Head::new();
|
||||||
let res = head.seek(SeekFrom::End(-10));
|
let res = head.seek(SeekFrom::End(-10));
|
||||||
|
|
||||||
let inner: u64 = head.into();
|
let inner: u64 = head.into();
|
||||||
assert_eq!(inner, u64::MAX - 10);
|
assert_eq!(inner, 65_535 - 10);
|
||||||
assert_eq!(res, Ok(inner));
|
assert_eq!(res, Some(inner));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn seek_end_overflow() {
|
||||||
|
let mut head: Head<65_535> = Head::new();
|
||||||
|
let res = head.seek(SeekFrom::End(10));
|
||||||
|
assert!(res.is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn seek_invalid_overflow() {
|
fn seek_invalid_overflow() {
|
||||||
let mut head = Head::new();
|
let mut head: Head<65_535> = Head::new();
|
||||||
let _ = head.seek(SeekFrom::Start(u64::MAX - 5));
|
let _ = head.seek(SeekFrom::Start(65_535 - 5));
|
||||||
|
|
||||||
let res = head.seek(SeekFrom::Current(10));
|
let res = head.seek(SeekFrom::Current(10));
|
||||||
assert!(res.is_err());
|
assert!(res.is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn seek_invalid_underflow() {
|
fn seek_invalid_underflow() {
|
||||||
let mut head = Head::new();
|
let mut head: Head<65_535> = Head::new();
|
||||||
|
|
||||||
let res = head.seek(SeekFrom::Current(-1));
|
let res = head.seek(SeekFrom::Current(-1));
|
||||||
assert!(res.is_err());
|
assert!(res.is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn convert_zero() {
|
fn convert_zero() {
|
||||||
let head = Head::new();
|
let head: Head<65_535> = Head::new();
|
||||||
let addr = head.memory_address();
|
let addr = head.memory_address();
|
||||||
|
|
||||||
assert_eq!(addr, Some([0, 0]));
|
assert_eq!(addr, Some([0, 0]));
|
||||||
@ -165,7 +188,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn convert_1_byte() {
|
fn convert_1_byte() {
|
||||||
let mut head = Head::new();
|
let mut head: Head<65_535> = Head::new();
|
||||||
let _ = head.seek(SeekFrom::Start(50));
|
let _ = head.seek(SeekFrom::Start(50));
|
||||||
|
|
||||||
let addr = head.memory_address();
|
let addr = head.memory_address();
|
||||||
@ -175,7 +198,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn convert_2_bytes() {
|
fn convert_2_bytes() {
|
||||||
let mut head = Head::new();
|
let mut head: Head<65_535> = Head::new();
|
||||||
let _ = head.seek(SeekFrom::Start(260));
|
let _ = head.seek(SeekFrom::Start(260));
|
||||||
|
|
||||||
let addr = head.memory_address();
|
let addr = head.memory_address();
|
||||||
@ -185,8 +208,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn convert_invalid() {
|
fn convert_invalid() {
|
||||||
let mut head = Head::new();
|
let mut head: Head<4_294_967_295> = Head::new(); // Needs to be more then u16::MAX
|
||||||
let _ = head.seek(SeekFrom::Start(u16::MAX as u64 + 1));
|
let _ = head.seek(SeekFrom::Start(65_536)); // One more then u16::MAX
|
||||||
|
|
||||||
let addr = head.memory_address();
|
let addr = head.memory_address();
|
||||||
assert!(addr.is_none());
|
assert!(addr.is_none());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user