1#![allow(unsafe_code)]
2
3#[cfg(test)]
4#[path = "./table_tests.rs"]
5mod tests;
6
7use crate::value::{
8 FLAG_HEADER, FLAG_MASK, FLAG_SHIFT, FLAG_TABLE, Item, Key, MaybeItem, NONE, TAG_MASK,
9 TAG_SHIFT, TAG_TABLE,
10};
11use crate::{Deserialize, Error, ErrorKind, Span};
12use std::mem::size_of;
13use std::ptr::NonNull;
14
15use crate::arena::Arena;
16
17type TableEntry<'de> = (Key<'de>, Item<'de>);
18
19const MIN_CAP: u32 = 2;
20
21#[repr(C, align(8))]
23pub(crate) struct InnerTable<'de> {
24 len: u32,
25 cap: u32,
26 ptr: NonNull<TableEntry<'de>>,
27}
28
29impl<'de> InnerTable<'de> {
30 #[inline]
32 pub fn new() -> Self {
33 Self {
34 len: 0,
35 cap: 0,
36 ptr: NonNull::dangling(),
37 }
38 }
39
40 pub fn insert(
42 &mut self,
43 key: Key<'de>,
44 item: Item<'de>,
45 arena: &Arena,
46 ) -> &mut TableEntry<'de> {
47 let len = self.len;
48 if self.len == self.cap {
49 self.grow(arena);
50 }
51 unsafe {
52 let ptr = self.ptr.as_ptr().add(len as usize);
53 ptr.write((key, item));
54 self.len = len + 1;
55 &mut (*ptr)
56 }
57 }
58
59 #[inline]
61 pub fn len(&self) -> usize {
62 self.len as usize
63 }
64
65 #[inline]
67 pub fn is_empty(&self) -> bool {
68 self.len == 0
69 }
70
71 pub fn get_key_value(&self, name: &str) -> Option<(&Key<'de>, &Item<'de>)> {
73 for entry in self.entries() {
74 if entry.0.name == name {
75 return Some((&entry.0, &entry.1));
76 }
77 }
78 None
79 }
80
81 pub fn get(&self, name: &str) -> Option<&Item<'de>> {
83 for entry in self.entries() {
84 if entry.0.name == name {
85 return Some(&entry.1);
86 }
87 }
88 None
89 }
90
91 pub fn get_mut(&mut self, name: &str) -> Option<&mut Item<'de>> {
93 for entry in self.entries_mut() {
94 if entry.0.name == name {
95 return Some(&mut entry.1);
96 }
97 }
98 None
99 }
100
101 #[inline]
103 pub fn contains_key(&self, name: &str) -> bool {
104 self.get(name).is_some()
105 }
106
107 pub fn remove(&mut self, name: &str) -> Option<Item<'de>> {
110 self.remove_entry(name).map(|(_, v)| v)
111 }
112
113 pub fn remove_entry(&mut self, name: &str) -> Option<(Key<'de>, Item<'de>)> {
116 let idx = self.find_index(name)?;
117 Some(self.remove_at(idx))
118 }
119
120 pub fn values_mut(&mut self) -> impl Iterator<Item = &mut Item<'de>> {
122 self.entries_mut().iter_mut().map(|(_, v)| v)
123 }
124
125 #[inline]
132 pub(crate) unsafe fn first_key_span_start_unchecked(&self) -> u32 {
133 debug_assert!(self.len > 0);
134 unsafe { (*self.ptr.as_ptr()).0.span.start }
135 }
136
137 #[inline]
139 pub fn entries(&self) -> &[TableEntry<'de>] {
140 unsafe { std::slice::from_raw_parts(self.ptr.as_ptr(), self.len as usize) }
141 }
142
143 #[inline]
144 pub(crate) fn entries_mut(&mut self) -> &mut [TableEntry<'de>] {
145 unsafe { std::slice::from_raw_parts_mut(self.ptr.as_ptr(), self.len as usize) }
146 }
147
148 pub(crate) fn find_index(&self, name: &str) -> Option<usize> {
149 for (i, entry) in self.entries().iter().enumerate() {
150 if entry.0.name == name {
151 return Some(i);
152 }
153 }
154 None
155 }
156
157 fn remove_at(&mut self, idx: usize) -> (Key<'de>, Item<'de>) {
159 let last = self.len as usize - 1;
160 let ptr = unsafe { self.ptr.as_ptr().add(idx) };
161 let entry = unsafe { ptr.read() };
162 if idx != last {
163 unsafe {
165 ptr.write(self.ptr.as_ptr().add(last).read());
166 }
167 }
168 self.len -= 1;
169 entry
170 }
171
172 #[cold]
173 fn grow(&mut self, arena: &Arena) {
174 let new_cap = if self.cap == 0 {
175 MIN_CAP
176 } else {
177 self.cap.checked_mul(2).expect("capacity overflow")
178 };
179 self.grow_to(new_cap, arena);
180 }
181
182 fn grow_to(&mut self, new_cap: u32, arena: &Arena) {
183 let new_size = new_cap as usize * size_of::<TableEntry<'_>>();
184 if self.cap > 0 {
185 let old_size = self.cap as usize * size_of::<TableEntry<'_>>();
186 self.ptr = unsafe { arena.realloc(self.ptr.cast(), old_size, new_size).cast() };
188 } else {
189 self.ptr = arena.alloc(new_size).cast();
190 }
191 self.cap = new_cap;
192 }
193}
194
195impl std::fmt::Debug for InnerTable<'_> {
196 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
197 let mut map = f.debug_map();
198 for (k, v) in self.entries() {
199 map.entry(k, v);
200 }
201 map.finish()
202 }
203}
204
205pub struct IntoIter<'de> {
207 table: InnerTable<'de>,
208 index: u32,
209}
210
211impl<'de> Iterator for IntoIter<'de> {
212 type Item = (Key<'de>, Item<'de>);
213
214 fn next(&mut self) -> Option<Self::Item> {
215 if self.index < self.table.len {
216 let entry = unsafe { self.table.ptr.as_ptr().add(self.index as usize).read() };
217 self.index += 1;
218 Some(entry)
219 } else {
220 None
221 }
222 }
223
224 fn size_hint(&self) -> (usize, Option<usize>) {
225 let remaining = (self.table.len - self.index) as usize;
226 (remaining, Some(remaining))
227 }
228}
229
230impl ExactSizeIterator for IntoIter<'_> {}
231
232#[repr(C)]
264pub struct Table<'de> {
265 pub(crate) value: InnerTable<'de>,
266 start_and_tag: u32,
268 end_and_flag: u32,
270}
271
272impl<'de> Table<'de> {
273 pub fn new(span: Span) -> Table<'de> {
275 Table {
276 start_and_tag: span.start << TAG_SHIFT | TAG_TABLE,
277 end_and_flag: (span.end << FLAG_SHIFT) | FLAG_TABLE,
278 value: InnerTable::new(),
279 }
280 }
281 pub fn span(&self) -> Span {
283 Span {
284 start: self.start_and_tag >> TAG_SHIFT,
285 end: self.end_and_flag >> FLAG_SHIFT,
286 }
287 }
288}
289
290impl<'de> Default for Table<'de> {
291 fn default() -> Self {
292 Self::new(Span::default())
293 }
294}
295
296impl std::fmt::Debug for Table<'_> {
297 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
298 self.value.fmt(f)
299 }
300}
301
302impl<'de> Table<'de> {
303 pub fn insert(&mut self, key: Key<'de>, value: Item<'de>, arena: &Arena) {
305 self.value.insert(key, value, arena);
306 }
307
308 #[inline]
310 pub fn len(&self) -> usize {
311 self.value.len()
312 }
313
314 #[inline]
316 pub fn is_empty(&self) -> bool {
317 self.value.is_empty()
318 }
319
320 pub fn get_key_value(&self, name: &str) -> Option<(&Key<'de>, &Item<'de>)> {
322 self.value.get_key_value(name)
323 }
324
325 pub fn get(&self, name: &str) -> Option<&Item<'de>> {
327 self.value.get(name)
328 }
329
330 pub fn get_mut(&mut self, name: &str) -> Option<&mut Item<'de>> {
332 self.value.get_mut(name)
333 }
334
335 #[inline]
337 pub fn contains_key(&self, name: &str) -> bool {
338 self.value.contains_key(name)
339 }
340
341 pub fn remove(&mut self, name: &str) -> Option<Item<'de>> {
344 self.value.remove(name)
345 }
346
347 pub fn remove_entry(&mut self, name: &str) -> Option<(Key<'de>, Item<'de>)> {
350 self.value.remove_entry(name)
351 }
352
353 pub fn values_mut(&mut self) -> impl Iterator<Item = &mut Item<'de>> {
355 self.value.values_mut()
356 }
357
358 #[inline]
360 pub fn entries(&self) -> &[TableEntry<'de>] {
361 self.value.entries()
362 }
363
364 pub fn into_item(self) -> Item<'de> {
366 let span = self.span();
367 Item::table(self.value, span)
368 }
369
370 pub fn required<T: Deserialize<'de>>(&mut self, name: &'static str) -> Result<T, Error> {
372 let Some(mut val) = self.value.remove(name) else {
373 return Err(Error {
374 kind: ErrorKind::MissingField(name),
375 span: self.span(),
376 });
377 };
378
379 T::deserialize(&mut val)
380 }
381
382 pub fn optional<T: Deserialize<'de>>(&mut self, name: &str) -> Result<Option<T>, Error> {
384 let Some(mut val) = self.value.remove(name) else {
385 return Ok(None);
386 };
387
388 match T::deserialize(&mut val) {
389 Ok(value) => Ok(Some(value)),
390 Err(err) => Err(err),
391 }
392 }
393
394 pub fn expect_empty(&self) -> Result<(), Error> {
399 if self.value.is_empty() {
400 return Ok(());
401 }
402
403 let mut keys = Vec::with_capacity(self.value.len());
412 for (key, _) in self.value.entries() {
413 keys.push((key.name.into(), key.span));
414 }
415
416 Err(Error::from((
417 ErrorKind::UnexpectedKeys { keys },
418 self.span(),
419 )))
420 }
421}
422
423impl<'a, 'de> IntoIterator for &'a mut Table<'de> {
424 type Item = &'a mut (Key<'de>, Item<'de>);
425 type IntoIter = std::slice::IterMut<'a, TableEntry<'de>>;
426
427 fn into_iter(self) -> Self::IntoIter {
428 self.value.entries_mut().iter_mut()
429 }
430}
431impl<'a, 'de> IntoIterator for &'a Table<'de> {
432 type Item = &'a (Key<'de>, Item<'de>);
433 type IntoIter = std::slice::Iter<'a, TableEntry<'de>>;
434
435 fn into_iter(self) -> Self::IntoIter {
436 self.value.entries().iter()
437 }
438}
439
440impl<'de> IntoIterator for Table<'de> {
441 type Item = (Key<'de>, Item<'de>);
442 type IntoIter = IntoIter<'de>;
443
444 fn into_iter(self) -> Self::IntoIter {
445 IntoIter {
446 table: self.value,
447 index: 0,
448 }
449 }
450}
451
452const _: () = assert!(std::mem::size_of::<Table<'_>>() == std::mem::size_of::<Item<'_>>());
453const _: () = assert!(std::mem::align_of::<Table<'_>>() == std::mem::align_of::<Item<'_>>());
454
455impl<'de> Table<'de> {
456 #[inline]
457 pub(crate) fn span_start(&self) -> u32 {
458 self.start_and_tag >> TAG_SHIFT
459 }
460
461 #[inline]
462 pub(crate) fn set_span_start(&mut self, v: u32) {
463 self.start_and_tag = (v << TAG_SHIFT) | (self.start_and_tag & TAG_MASK);
464 }
465
466 #[inline]
467 pub(crate) fn set_span_end(&mut self, v: u32) {
468 self.end_and_flag = (v << FLAG_SHIFT) | (self.end_and_flag & FLAG_MASK);
469 }
470
471 #[inline]
472 pub(crate) fn extend_span_end(&mut self, new_end: u32) {
473 let old = self.end_and_flag;
474 let current = old >> FLAG_SHIFT;
475 self.end_and_flag = (current.max(new_end) << FLAG_SHIFT) | (old & FLAG_MASK);
476 }
477
478 #[inline]
479 pub(crate) fn set_header_flag(&mut self) {
480 self.end_and_flag = (self.end_and_flag & !FLAG_MASK) | FLAG_HEADER;
481 }
482}
483
484impl<'de> std::ops::Index<&str> for Table<'de> {
485 type Output = MaybeItem<'de>;
486
487 #[inline]
488 fn index(&self, index: &str) -> &Self::Output {
489 if let Some(item) = self.get(index) {
490 return MaybeItem::from_ref(item);
491 }
492 &NONE
493 }
494}