use crate::Error;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LinearMemorySpec<'a> {
pub heap: HeapSpec,
#[serde(borrow)]
pub initializer: SparseData<'a>,
}
pub struct OwnedLinearMemorySpec {
pub heap: HeapSpec,
pub initializer: OwnedSparseData,
}
impl OwnedLinearMemorySpec {
pub fn to_ref<'a>(&'a self) -> LinearMemorySpec<'a> {
LinearMemorySpec {
heap: self.heap.clone(),
initializer: self.initializer.to_ref(),
}
}
}
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct HeapSpec {
pub reserved_size: u64,
pub guard_size: u64,
pub initial_size: u64,
pub max_size: Option<u64>,
}
impl HeapSpec {
pub fn new(
reserved_size: u64,
guard_size: u64,
initial_size: u64,
max_size: Option<u64>,
) -> Self {
Self {
reserved_size,
guard_size,
initial_size,
max_size,
}
}
pub fn empty() -> Self {
Self {
reserved_size: 0,
guard_size: 0,
initial_size: 0,
max_size: None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SparseData<'a> {
#[serde(borrow)]
pages: Vec<Option<&'a [u8]>>,
}
impl<'a> SparseData<'a> {
pub fn new(pages: Vec<Option<&'a [u8]>>) -> Result<Self, Error> {
if !pages.iter().all(|page| match page {
Some(contents) => contents.len() == 4096,
None => true,
}) {
return Err(Error::IncorrectPageSize);
}
Ok(Self { pages })
}
pub fn pages(&self) -> &[Option<&'a [u8]>] {
&self.pages
}
pub fn get_page(&self, offset: usize) -> &Option<&'a [u8]> {
self.pages.get(offset).unwrap_or(&None)
}
pub fn len(&self) -> usize {
self.pages.len()
}
}
pub struct OwnedSparseData {
pages: Vec<Option<Vec<u8>>>,
}
impl OwnedSparseData {
pub fn new(pages: Vec<Option<Vec<u8>>>) -> Result<Self, Error> {
if !pages.iter().all(|page| match page {
Some(contents) => contents.len() == 4096,
None => true,
}) {
return Err(Error::IncorrectPageSize);
}
Ok(Self { pages })
}
pub fn to_ref<'a>(&'a self) -> SparseData<'a> {
SparseData::new(
self.pages
.iter()
.map(|c| match c {
Some(data) => Some(data.as_slice()),
None => None,
})
.collect(),
)
.expect("SparseData invariant enforced by OwnedSparseData constructor")
}
}