ruby_marshal/
value_arena.rs1mod value;
2mod value_handle;
3
4pub use self::value::ArrayValue;
5pub use self::value::BoolValue;
6pub use self::value::FixnumValue;
7pub use self::value::HashValue;
8pub use self::value::NilValue;
9pub use self::value::ObjectValue;
10pub use self::value::StringValue;
11pub use self::value::SymbolValue;
12pub use self::value::UserDefinedValue;
13pub use self::value::Value;
14pub use self::value::ValueKind;
15pub use self::value_handle::TypedValueHandle;
16pub use self::value_handle::ValueHandle;
17use slotmap::SlotMap;
18use std::collections::HashMap;
19
20#[derive(Debug)]
22pub struct ValueArena {
23 arena: SlotMap<slotmap::DefaultKey, Value>,
24 symbols: HashMap<Vec<u8>, TypedValueHandle<SymbolValue>>,
25 root: ValueHandle,
26}
27
28impl ValueArena {
29 pub fn new() -> Self {
33 let mut arena = SlotMap::new();
34 let symbols = HashMap::new();
35 let root = ValueHandle::new(arena.insert(Value::Nil(NilValue)));
36
37 Self {
38 arena,
39 symbols,
40 root,
41 }
42 }
43
44 pub fn root(&self) -> ValueHandle {
46 self.root
47 }
48
49 pub fn replace_root<H>(&mut self, new_root: H) -> ValueHandle
51 where
52 H: Into<ValueHandle>,
53 {
54 let mut new_root = new_root.into();
55
56 std::mem::swap(&mut self.root, &mut new_root);
57 new_root
58 }
59
60 pub fn get<H>(&self, handle: H) -> Option<&Value>
62 where
63 H: Into<ValueHandle>,
64 {
65 self.arena.get(handle.into().index)
66 }
67
68 pub(crate) fn get_mut<H>(&mut self, handle: H) -> Option<&mut Value>
70 where
71 H: Into<ValueHandle>,
72 {
73 self.arena.get_mut(handle.into().index)
74 }
75
76 pub fn get_symbol(&self, handle: TypedValueHandle<SymbolValue>) -> Option<&SymbolValue> {
81 Some(self.get(handle)?.as_symbol().expect("not a symbol"))
82 }
83
84 pub fn create_nil(&mut self) -> TypedValueHandle<NilValue> {
86 let index = self.arena.insert(Value::Nil(NilValue));
87 let handle = ValueHandle::new(index);
88
89 TypedValueHandle::new_unchecked(handle)
90 }
91
92 pub fn create_bool(&mut self, value: bool) -> TypedValueHandle<BoolValue> {
94 let index = self.arena.insert(Value::Bool(BoolValue::new(value)));
95 let handle = ValueHandle::new(index);
96
97 TypedValueHandle::new_unchecked(handle)
98 }
99
100 pub fn create_fixnum(&mut self, value: i32) -> TypedValueHandle<FixnumValue> {
102 let index = self.arena.insert(Value::Fixnum(FixnumValue::new(value)));
103 let handle = ValueHandle::new(index);
104
105 TypedValueHandle::new_unchecked(handle)
106 }
107
108 pub fn create_symbol(&mut self, value: Vec<u8>) -> TypedValueHandle<SymbolValue> {
112 if let Some(handle) = self.symbols.get(&value) {
113 return *handle;
114 }
115
116 self.create_new_symbol(value)
117 }
118
119 pub fn create_new_symbol(&mut self, value: Vec<u8>) -> TypedValueHandle<SymbolValue> {
121 let index = self
122 .arena
123 .insert(Value::Symbol(SymbolValue::new(value.clone())));
124 let handle = ValueHandle::new(index);
125 let handle = TypedValueHandle::new_unchecked(handle);
126
127 self.symbols.entry(value).or_insert(handle);
128
129 handle
130 }
131
132 pub fn create_array(&mut self, value: Vec<ValueHandle>) -> TypedValueHandle<ArrayValue> {
134 let index = self.arena.insert(Value::Array(ArrayValue::new(value)));
135 let handle = ValueHandle::new(index);
136
137 TypedValueHandle::new_unchecked(handle)
138 }
139
140 pub fn create_hash(
142 &mut self,
143 value: Vec<(ValueHandle, ValueHandle)>,
144 default_value: Option<ValueHandle>,
145 ) -> TypedValueHandle<HashValue> {
146 let index = self
147 .arena
148 .insert(Value::Hash(HashValue::new(value, default_value)));
149 let handle = ValueHandle::new(index);
150
151 TypedValueHandle::new_unchecked(handle)
152 }
153
154 pub fn create_object(
156 &mut self,
157 name: TypedValueHandle<SymbolValue>,
158 instance_variables: Vec<(TypedValueHandle<SymbolValue>, ValueHandle)>,
159 ) -> TypedValueHandle<ObjectValue> {
160 let index = self
161 .arena
162 .insert(Value::Object(ObjectValue::new(name, instance_variables)));
163 let handle = ValueHandle::new(index);
164
165 TypedValueHandle::new_unchecked(handle)
166 }
167
168 pub fn create_string(&mut self, value: Vec<u8>) -> TypedValueHandle<StringValue> {
170 let index = self.arena.insert(Value::String(StringValue::new(value)));
171 let handle = ValueHandle::new(index);
172
173 TypedValueHandle::new_unchecked(handle)
174 }
175
176 pub fn create_user_defined(
178 &mut self,
179 name: TypedValueHandle<SymbolValue>,
180 value: Vec<u8>,
181 ) -> TypedValueHandle<UserDefinedValue> {
182 let index = self
183 .arena
184 .insert(Value::UserDefined(UserDefinedValue::new(name, value)));
185 let handle = ValueHandle::new(index);
186
187 TypedValueHandle::new_unchecked(handle)
188 }
189}
190
191impl Default for ValueArena {
192 fn default() -> Self {
193 Self::new()
194 }
195}
196
197impl std::ops::Index<ValueHandle> for ValueArena {
198 type Output = Value;
199
200 fn index(&self, index: ValueHandle) -> &Self::Output {
201 self.get(index).expect("missing value")
202 }
203}