rune/indexing/
items.rs
1use core::fmt;
2
3use crate::alloc;
4use crate::alloc::prelude::*;
5use crate::item::ComponentRef;
6use crate::{Item, ItemBuf};
7
8#[derive(Debug)]
9#[non_exhaustive]
10pub(crate) struct MissingLastId;
11
12impl fmt::Display for MissingLastId {
13 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14 write!(f, "Missing last inserted id into the items stack")
15 }
16}
17
18impl core::error::Error for MissingLastId {}
19
20#[derive(Debug)]
21#[non_exhaustive]
22pub(crate) struct GuardMismatch {
23 actual: usize,
24 expected: usize,
25}
26
27impl fmt::Display for GuardMismatch {
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29 write!(
30 f,
31 "Guard mismatch when popping items, {} (actual) != {} (expected)",
32 self.actual, self.expected
33 )
34 }
35}
36
37impl core::error::Error for GuardMismatch {}
38
39#[derive(Debug)]
41#[must_use]
42pub(crate) struct Guard(usize);
43
44#[derive(Debug)]
46pub(crate) struct Items {
47 item: ItemBuf,
48}
49
50impl Items {
51 pub(crate) fn new(item: &Item) -> alloc::Result<Self> {
53 Ok(Self {
54 item: item.try_to_owned()?,
55 })
56 }
57
58 pub(crate) fn item(&self) -> &Item {
60 &self.item
61 }
62
63 pub(super) fn push_id(&mut self, id: usize) -> alloc::Result<Guard> {
65 self.item.push(ComponentRef::Id(id))?;
66 Ok(Guard(self.item.as_bytes().len()))
67 }
68
69 pub(super) fn push_name(&mut self, name: &str) -> alloc::Result<Guard> {
71 self.item.push(name)?;
72 Ok(Guard(self.item.as_bytes().len()))
73 }
74
75 pub(super) fn pop(&mut self, Guard(expected): Guard) -> Result<(), GuardMismatch> {
77 if self.item.as_bytes().len() != expected {
78 return Err(GuardMismatch {
79 actual: self.item.as_bytes().len(),
80 expected,
81 });
82 }
83
84 self.item.pop();
85 Ok(())
86 }
87}