roussillon_memory/
region.rs1use 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}