use super::memory_manager::{
MEMORY_MANAGER_INVALID_ID, MEMORY_MANAGER_MAX_ID, MEMORY_MANAGER_MIN_ID,
};
use serde::{Deserialize, Deserializer, Serialize, de::Error as _};
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
pub struct MemoryManagerIdRange {
start: u8,
end: u8,
}
impl<'de> Deserialize<'de> for MemoryManagerIdRange {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
#[derive(Deserialize)]
#[serde(rename = "MemoryManagerIdRange", deny_unknown_fields)]
struct Bounds {
start: u8,
end: u8,
}
let bounds = Bounds::deserialize(deserializer)?;
Self::new(bounds.start, bounds.end).map_err(D::Error::custom)
}
}
impl MemoryManagerIdRange {
pub const fn new(start: u8, end: u8) -> Result<Self, MemoryManagerRangeError> {
if start > end {
return Err(MemoryManagerRangeError::InvalidRange { start, end });
}
if end == MEMORY_MANAGER_INVALID_ID {
return Err(MemoryManagerRangeError::InvalidMemoryManagerId { id: end });
}
Ok(Self { start, end })
}
#[must_use]
pub const fn all_usable() -> Self {
Self {
start: MEMORY_MANAGER_MIN_ID,
end: MEMORY_MANAGER_MAX_ID,
}
}
#[must_use]
pub const fn contains(&self, id: u8) -> bool {
id >= self.start && id <= self.end
}
#[must_use]
pub const fn start(&self) -> u8 {
self.start
}
#[must_use]
pub const fn end(&self) -> u8 {
self.end
}
}
#[non_exhaustive]
#[derive(Clone, Copy, Debug, Eq, thiserror::Error, PartialEq)]
pub enum MemoryManagerRangeError {
#[error("MemoryManager ID range is invalid: start={start} end={end}")]
InvalidRange {
start: u8,
end: u8,
},
#[error("MemoryManager ID {id} is not a usable allocation slot")]
InvalidMemoryManagerId {
id: u8,
},
}