swamp_core_extra/
extra.rs1use crate::idx_gen::IndexAllocator;
6use crate::qck_des::quick_deserialize;
7use crate::value::{QuickDeserialize, Value, to_rust_value};
8use crate::value::{QuickSerialize, ValueRef};
9use sparse_slot::{Id, SparseSlot};
10use std::cell::RefCell;
11use std::fmt::{Debug, Display, Formatter};
12use std::rc::Rc;
13use swamp_types::ExternalType;
14use swamp_types::Type;
15
16#[derive(Debug, PartialEq, Eq)]
17pub struct SparseValueId(pub Id);
18
19impl Display for SparseValueId {
20 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
21 write!(f, "id:{}:{}", self.0.index, self.0.generation)
22 }
23}
24
25impl QuickDeserialize for SparseValueId {
26 fn quick_deserialize(octets: &[u8]) -> (Self, usize) {
27 let mut offset = 0;
28
29 let index = u16::from_le_bytes(octets[offset..offset + 2].try_into().unwrap());
31 offset += 2;
32
33 let generation = u8::from_le_bytes(octets[offset..=offset].try_into().unwrap());
35 offset += 1;
36
37 let id = Id::new(index.into(), generation);
38
39 (SparseValueId(id), offset)
40 }
41}
42
43impl QuickSerialize for SparseValueId {
44 fn quick_serialize(&self, octets: &mut [u8]) -> usize {
45 let mut offset = 0;
46
47 let index_octets = (self.0.index as u16).to_le_bytes();
49 octets[offset..offset + index_octets.len()].copy_from_slice(&index_octets);
50 offset += index_octets.len();
51
52 let generation_octets = self.0.generation.to_le_bytes();
54 octets[offset..offset + generation_octets.len()].copy_from_slice(&generation_octets);
55 offset += generation_octets.len();
56
57 offset
58 }
59}
60
61#[derive()]
62pub struct SparseValueMap {
63 pub sparse_slot: SparseSlot<Rc<RefCell<Value>>>,
64 pub id_generator: IndexAllocator,
65 pub value_item_type: Type,
66 pub rust_type_ref_for_id: ExternalType,
67}
68
69impl Debug for SparseValueMap {
70 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
71 writeln!(f, "SparseValueMap")?;
72
73 for (id, val) in self.sparse_slot.iter() {
74 writeln!(f, " {id}: {}", val.borrow())?;
75 }
76
77 Ok(())
78 }
79}
80
81impl QuickSerialize for SparseValueMap {
82 fn quick_serialize(&self, octets: &mut [u8]) -> usize {
83 let mut offset = 0;
84
85 let count = self.sparse_slot.len() as u16;
86 let count_octets = count.to_le_bytes();
87 octets[offset..offset + count_octets.len()].copy_from_slice(&count_octets);
88 offset += count_octets.len();
89
90 for (id, value) in self.sparse_slot.iter() {
91 let short_index = id.index as u16;
92 let key_index_octets = short_index.to_le_bytes();
93 octets[offset..offset + key_index_octets.len()].copy_from_slice(&key_index_octets);
94 offset += key_index_octets.len();
95
96 let key_generation_octets = id.generation.to_le_bytes();
97 octets[offset..offset + key_generation_octets.len()]
98 .copy_from_slice(&key_generation_octets);
99 offset += key_generation_octets.len();
100
101 let value_size = value.borrow().quick_serialize(&mut octets[offset..], 0);
102 offset += value_size;
103 }
104
105 offset
106 }
107}
108
109impl SparseValueMap {
110 #[must_use]
113 pub fn quick_deserialize(
114 key_type: ExternalType,
115 value_item_type: &Type,
116 octets: &[u8],
117 ) -> (Self, usize) {
118 let mut sparse = Self::new(key_type, value_item_type.clone());
119 let mut offset = 0;
120 let count = u16::from_le_bytes(
121 octets[offset..offset + 2]
122 .try_into()
123 .expect("could not convert to u16 count"),
124 );
125 offset += 2;
126
127 for _i in 0..count {
128 let index = u16::from_le_bytes(
129 octets[offset..offset + 2]
130 .try_into()
131 .expect("could not convert to u16 index"),
132 );
133 offset += 2;
134
135 let generation = u8::from_le_bytes(
136 octets[offset..=offset]
137 .try_into()
138 .expect("could not convert to u16 generation"),
139 );
140 offset += 1;
141
142 let (value, octet_size) =
143 quick_deserialize(&value_item_type.clone(), &octets[offset..], 0);
144 offset += octet_size;
145
146 let id = Id::new(index as usize, generation);
147 let deserialized_value_ref = Rc::new(RefCell::new(value));
148 sparse
149 .sparse_slot
150 .try_set(id, deserialized_value_ref)
151 .expect("could not insert into SparseValueMap");
152
153 sparse.id_generator.reserve(index as usize, generation);
154 }
155
156 (sparse, offset)
157 }
158}
159
160impl Display for SparseValueMap {
161 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
162 write!(
163 f,
164 "Sparse<{:?}> len:{}",
165 self.value_item_type,
166 self.sparse_slot.len()
167 )
168 }
169}
170
171impl SparseValueMap {
172 #[must_use]
173 pub fn new(rust_type_ref_for_id: ExternalType, value_item_type: Type) -> Self {
174 Self {
180 sparse_slot: SparseSlot::<Rc<RefCell<Value>>>::new(2048),
181 id_generator: IndexAllocator::new(),
182 value_item_type,
183 rust_type_ref_for_id,
184 }
185 }
186
187 pub fn add(&mut self, v: Value) -> Value {
190 let (index, generation) = self.id_generator.create();
192
193 let id = Id { index, generation };
194
195 let mutable_reference = Rc::new(RefCell::new(v));
197
198 self.sparse_slot
199 .try_set(id, mutable_reference)
200 .expect("sparse should work");
201
202 let script_id = SparseValueId(id);
203
204 to_rust_value(self.rust_type_ref_for_id.clone(), script_id)
205 }
206
207 pub fn remove(&mut self, id: &SparseValueId) {
208 self.id_generator.remove((id.0.index, id.0.generation));
209 self.sparse_slot.remove(id.0);
210 }
211
212 #[must_use]
213 pub fn get(&self, id: &SparseValueId) -> Option<&ValueRef> {
214 self.sparse_slot.get(id.0)
215 }
216
217 #[allow(unused)]
218 #[must_use]
219 pub fn iter(&self) -> sparse_slot::Iter<'_, Rc<RefCell<Value>>> {
220 self.sparse_slot.iter()
221 }
222
223 pub fn iter_mut(&mut self) -> sparse_slot::IterMut<'_, Rc<RefCell<Value>>> {
224 self.sparse_slot.iter_mut()
225 }
226
227 #[must_use]
228 pub fn values(&self) -> Vec<Rc<RefCell<Value>>> {
229 self.sparse_slot.iter().map(|(_id, v)| v.clone()).collect()
230 }
231}