1use crate::syntax::{Expression, Path, Root};
2
3#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
4pub enum Step {
5 Field(String),
6 Item,
7}
8
9#[derive(Default)]
11pub(crate) struct Slots {
12 slots: Vec<Option<Vec<Step>>>,
14}
15
16impl Slots {
17 pub(crate) fn push_items(&mut self, list: &Expression) {
18 let items = self.items_of(list);
19 self.slots.push(items);
20 }
21
22 pub(crate) fn push_dataless(&mut self) {
23 self.slots.push(None);
24 }
25
26 #[cfg(feature = "gates")]
27 pub(crate) fn depth(&self) -> usize {
28 self.slots.len()
29 }
30
31 pub(crate) fn truncate(&mut self, depth: usize) {
32 self.slots.truncate(depth);
33 }
34
35 pub(crate) fn steps_of(&self, path: &Path) -> Option<Vec<Step>> {
36 let mut steps = match path.root {
37 Root::Data => Vec::new(),
38 Root::Slot(slot) => self.slots.get(slot)?.clone()?,
39 };
40 steps.extend(path.fields.iter().cloned().map(Step::Field));
41 Some(steps)
42 }
43
44 pub(crate) fn items_of(&self, list: &Expression) -> Option<Vec<Step>> {
45 let Expression::Path(path) = list else {
46 return None;
47 };
48 let mut steps = self.steps_of(path)?;
49 steps.push(Step::Item);
50 Some(steps)
51 }
52}