use std::fmt::Display;
use jstd::{Identifier, registry::Identified, registry::Registry};
use serde::{Deserialize, Serialize};
#[derive(Identifier)]
pub struct SpaceId(usize);
pub const SPACE_CONST: SpaceId = SpaceId(0);
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SpaceType {
Ram,
Rom,
Register,
Unique,
}
pub type SpaceRef<'ctx> = Identified<SpaceId, &'ctx Space>;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Space {
pub name: Option<Box<str>>,
pub word_size: usize,
pub addr_size: usize,
pub ty: SpaceType,
}
pub trait SpaceStore {
fn spaces(&self) -> &Registry<SpaceId, Space>;
}
impl Space {
pub fn new(name: Option<&str>, word_size: usize, addr_size: usize) -> Self {
Self {
name: name.map(Box::from),
word_size,
addr_size,
ty: SpaceType::Ram,
}
}
pub fn unique(addr_size: usize) -> Self {
Self {
name: Some(Box::from("unique")),
word_size: 1,
addr_size,
ty: SpaceType::Unique,
}
}
pub fn from_id<S: SpaceStore + ?Sized>(src: &S, id: SpaceId) -> SpaceRef<'_> {
SpaceRef::new(id, &src.spaces()[id])
}
}
impl Display for Space {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(name) = &self.name {
write!(f, "{}", name)
} else {
write!(f, "space")
}
}
}