rune/core/object/
chartab.rs1use super::{CloneIn, Gc, IntoObject, NIL, Object, WithLifetime};
2use crate::{
3 core::gc::{Block, GcHeap, Slot},
4 derive_GcMoveable,
5};
6use rune_core::hashmap::HashMap;
7use rune_macros::Trace;
8use std::{cell::RefCell, fmt};
9
10#[derive(Debug, Eq, Trace)]
11pub struct CharTableInner<'ob> {
12 parent: RefCell<Option<Slot<&'ob CharTable>>>,
13 data: RefCell<HashMap<usize, Slot<Object<'ob>>>>,
14 init: Slot<Object<'ob>>,
15}
16
17impl<'ob> CharTableInner<'ob> {
18 pub fn new(init: Option<Object<'ob>>) -> Self {
19 CharTableInner {
20 parent: RefCell::new(None),
21 data: RefCell::new(HashMap::default()),
22 init: Slot::new(init.unwrap_or(NIL)),
23 }
24 }
25}
26
27#[derive(PartialEq, Eq, Trace, Debug)]
28pub(crate) struct CharTable(GcHeap<CharTableInner<'static>>);
29
30derive_GcMoveable!(CharTable);
31
32impl PartialEq for CharTableInner<'_> {
33 fn eq(&self, other: &Self) -> bool {
34 std::ptr::eq(self, other)
35 }
36}
37
38impl<'new> CloneIn<'new, &'new Self> for CharTable {
39 fn clone_in<const C: bool>(&self, bk: &'new Block<C>) -> Gc<&'new Self> {
40 let parent_clone =
41 self.0.parent.borrow().as_ref().map(|p| Slot::new(p.clone_in(bk).untag()));
42 let parent = RefCell::new(parent_clone);
43
44 let mut data = HashMap::default();
45 for (key, value) in self.0.data.borrow().iter() {
46 let new_value = Slot::new(value.clone_in(bk));
47 data.insert(*key, new_value);
48 }
49 let data = RefCell::new(data);
50 let init = Slot::new(self.0.init.clone_in(bk));
51 CharTableInner { parent, data, init }.into_obj(bk)
52 }
53}
54
55impl CharTable {
56 pub(in crate::core) unsafe fn new(table: CharTableInner<'_>, constant: bool) -> Self {
57 let table =
59 unsafe { std::mem::transmute::<CharTableInner<'_>, CharTableInner<'static>>(table) };
60 Self(GcHeap::new(table, constant))
61 }
62
63 pub fn get(&self, idx: usize) -> Object {
64 match self.0.data.borrow().get(&idx) {
65 Some(x) => **x,
66 None => *self.0.init,
67 }
68 }
69
70 pub fn set(&self, idx: usize, item: Object) {
71 unsafe { self.0.data.borrow_mut().insert(idx, Slot::new(item.with_lifetime())) };
72 }
73
74 pub fn set_parent(&self, new: Option<&Self>) {
75 let new_ptr = new.map(|n| unsafe { Slot::new(n.with_lifetime()) });
76 *self.0.parent.borrow_mut() = new_ptr;
77 }
78}
79
80impl fmt::Display for CharTable {
81 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82 write!(f, "[")?;
83 let data = self.0.data.borrow();
84
85 let mut entries: Vec<_> = data.iter().collect();
86 entries.sort_by_key(|&(key, _)| key);
87
88 let mut iter = entries.into_iter();
89 if let Some((_, first)) = iter.next() {
90 write!(f, "{}", first)?;
91 for (_, value) in iter {
92 write!(f, " {}", value)?;
93 }
94 }
95 write!(f, "]")
96 }
97}