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