Skip to main content

roussillon_memory/
region.rs

1use std::collections::HashMap;
2use roussillon_type_system::identity::Label;
3use roussillon_type_system::value::reference::Reference;
4use roussillon_type_system::value::concept::{DataValue, ValueCell};
5
6pub trait Allocator<R=Reference, C=ValueCell> {
7    fn allocate(&mut self, cell: C) -> R;
8}
9
10pub trait Dereference<R=Reference, C=ValueCell> {
11    fn dereference(&self, reference: R) -> Option<C>;
12    fn validate(&self, reference: &R) -> bool;
13}
14
15#[derive(Clone, Default, Debug)]
16pub struct Region {
17    raw: Vec<u8>,
18}
19
20impl Region {
21    pub fn len(&self) -> usize { self.raw.len() }
22    pub fn is_empty(&self) -> bool { self.raw.is_empty() }
23}
24
25impl Allocator for Region {
26    fn allocate(&mut self, cell: ValueCell) -> Reference {
27        let address = self.raw.len();
28        let borrowed_cell = cell.borrow();
29        self.raw.extend_from_slice(&borrowed_cell.raw());
30        Reference::new(
31            borrowed_cell.data_type().clone(),
32            address,
33        )
34    }
35}
36
37impl Dereference for Region {
38    fn dereference(&self, reference: Reference) -> Option<ValueCell> {
39        let start = reference.get_address();
40        let referenced_type = reference.referenced();
41        let end = start + referenced_type.size();
42        if end > self.raw.len() { return None; };
43        let raw = &self.raw[start..end];
44        Some(referenced_type.construct_from_raw(raw).unwrap())
45    }
46
47    fn validate(&self, reference: &Reference) -> bool {
48        (reference.get_address() + reference.data_type().size()) < self.len()
49    }
50}
51
52#[derive(Clone, Debug, Default)]
53pub struct Area {
54    regions: HashMap<String, Region>,
55}
56
57impl Area {
58    pub fn new() -> Self { Self { regions: HashMap::new() } }
59
60    pub fn get(&self, label: &Label) -> Option<&Region> {
61        self.regions.get(&label.to_string())
62    }
63    
64    pub fn take(&mut self, label: &Label) -> Option<Region> {
65        self.regions.remove(&label.to_string())
66    }
67    
68    pub fn set(&mut self, label: &Label, region: Region) -> Option<Region> {
69        self.regions.insert(label.to_string(), region)
70    }
71}
72
73
74#[derive(Clone, Debug)]
75pub enum DroppableRegion {
76    Alive(Region),
77    Dropped,
78}
79
80impl DroppableRegion {
81    pub fn is_alive(&self) -> bool {
82        matches!(self, Self::Alive(_))
83    }
84
85    pub fn is_dropped(&self) -> bool {
86        matches!(self, Self::Dropped)
87    }
88
89    pub fn unwrap(&self) -> &Region {
90        match self {
91            DroppableRegion::Alive(region) => region,
92            DroppableRegion::Dropped => panic!("Attempted to unwrap a dropped region"),
93        }
94    }
95
96    pub fn unwrap_mut(&mut self) -> &mut Region {
97        match self {
98            DroppableRegion::Alive(region) => region,
99            DroppableRegion::Dropped => panic!("Attempted to unwrap a dropped region"),
100        }
101    }
102}