use alloc::borrow::Cow;
use wasefire_error::{Code, Error};
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct StorageIndex {
pub page: usize,
pub byte: usize,
}
pub trait Storage {
fn word_size(&self) -> usize;
fn page_size(&self) -> usize;
fn num_pages(&self) -> usize;
fn max_word_writes(&self) -> usize;
fn max_page_erases(&self) -> usize;
fn read_slice(&self, index: StorageIndex, length: usize) -> Result<Cow<'_, [u8]>, Error>;
fn write_slice(&mut self, index: StorageIndex, value: &[u8]) -> Result<(), Error>;
fn erase_page(&mut self, page: usize) -> Result<(), Error>;
}
impl StorageIndex {
fn is_valid(self, length: usize, storage: &impl Storage) -> bool {
let page_size = storage.page_size();
self.page < storage.num_pages() && length <= page_size && self.byte <= page_size - length
}
pub fn range(
self, length: usize, storage: &impl Storage,
) -> Result<core::ops::Range<usize>, Error> {
if self.is_valid(length, storage) {
let start = self.page * storage.page_size() + self.byte;
Ok(start .. start + length)
} else {
Err(Error::user(Code::OutOfBounds))
}
}
}