1use std::{
2 iter,
3 ops::{Bound, Index, IndexMut, RangeBounds},
4 slice::{self, SliceIndex},
5};
6
7use allocator_api2::vec;
8use gc_arena::allocator_api::MetricsAlloc;
9
10use crate::{Context, FromMultiValue, FromValue, IntoMultiValue, IntoValue, TypeError, Value};
11
12pub struct Stack<'gc, 'a> {
13 values: &'a mut vec::Vec<Value<'gc>, MetricsAlloc<'gc>>,
14 bottom: usize,
15}
16
17impl<'gc, 'a> Stack<'gc, 'a> {
18 pub fn new(values: &'a mut vec::Vec<Value<'gc>, MetricsAlloc<'gc>>, bottom: usize) -> Self {
19 assert!(values.len() >= bottom);
20 Self { values, bottom }
21 }
22
23 pub fn sub_stack(&mut self, bottom: usize) -> Stack<'gc, '_> {
24 Stack {
25 values: self.values,
26 bottom: self.bottom + bottom,
27 }
28 }
29
30 pub fn get(&self, i: usize) -> Value<'gc> {
31 self.values
32 .get(self.bottom + i)
33 .copied()
34 .unwrap_or_default()
35 }
36
37 pub fn push_back(&mut self, value: Value<'gc>) {
38 self.values.push(value);
39 }
40
41 pub fn push_front(&mut self, value: Value<'gc>) {
42 self.values.insert(self.bottom, value);
43 }
44
45 pub fn pop_back(&mut self) -> Value<'gc> {
46 if self.values.len() > self.bottom {
47 self.values.pop().unwrap()
48 } else {
49 Value::Nil
50 }
51 }
52
53 pub fn pop_front(&mut self) -> Value<'gc> {
54 if self.values.len() > self.bottom {
55 self.values.remove(self.bottom)
56 } else {
57 Value::Nil
58 }
59 }
60
61 pub fn len(&self) -> usize {
62 self.values.len() - self.bottom
63 }
64
65 pub fn is_empty(&self) -> bool {
66 self.values.len() == self.bottom
67 }
68
69 pub fn clear(&mut self) {
70 self.values.truncate(self.bottom);
71 }
72
73 pub fn resize(&mut self, size: usize) {
74 self.values.resize(self.bottom + size, Value::Nil);
75 }
76
77 pub fn drain<R: RangeBounds<usize>>(
78 &mut self,
79 range: R,
80 ) -> vec::Drain<Value<'gc>, MetricsAlloc<'gc>> {
81 let start = match range.start_bound().cloned() {
82 Bound::Included(r) => Bound::Included(self.bottom + r),
83 Bound::Excluded(r) => Bound::Excluded(self.bottom + r),
84 Bound::Unbounded => Bound::Included(self.bottom),
85 };
86 let end = match range.end_bound().cloned() {
87 Bound::Included(r) => Bound::Included(self.bottom + r),
88 Bound::Excluded(r) => Bound::Excluded(self.bottom + r),
89 Bound::Unbounded => Bound::Unbounded,
90 };
91 self.values.drain((start, end))
92 }
93
94 pub fn into_back(&mut self, ctx: Context<'gc>, v: impl IntoMultiValue<'gc>) {
95 for v in v.into_multi_value(ctx) {
96 self.values.push(v.into_value(ctx));
97 }
98 }
99
100 pub fn into_front(&mut self, ctx: Context<'gc>, v: impl IntoMultiValue<'gc>) {
101 let mut c = 0;
102 for v in v.into_multi_value(ctx) {
103 c += 1;
104 self.values.push(v.into_value(ctx));
105 }
106 self.values[self.bottom..].rotate_right(c);
107 }
108
109 pub fn from_back<V: FromValue<'gc>>(&mut self, ctx: Context<'gc>) -> Result<V, TypeError> {
110 V::from_value(ctx, self.pop_back())
111 }
112
113 pub fn from_front<V: FromValue<'gc>>(&mut self, ctx: Context<'gc>) -> Result<V, TypeError> {
114 V::from_value(ctx, self.pop_front())
115 }
116
117 pub fn replace(&mut self, ctx: Context<'gc>, v: impl IntoMultiValue<'gc>) {
118 self.clear();
119 self.extend(v.into_multi_value(ctx));
120 }
121
122 pub fn consume<V: FromMultiValue<'gc>>(&mut self, ctx: Context<'gc>) -> Result<V, TypeError> {
123 V::from_multi_value(ctx, self.drain(..))
124 }
125}
126
127impl<'gc: 'b, 'a, 'b> IntoIterator for &'b Stack<'gc, 'a> {
128 type Item = Value<'gc>;
129 type IntoIter = iter::Copied<slice::Iter<'b, Value<'gc>>>;
130
131 fn into_iter(self) -> Self::IntoIter {
132 self.values[self.bottom..].iter().copied()
133 }
134}
135
136impl<'gc, 'a> Extend<Value<'gc>> for Stack<'gc, 'a> {
137 fn extend<T: IntoIterator<Item = Value<'gc>>>(&mut self, iter: T) {
138 self.values.extend(iter);
139 }
140}
141
142impl<'gc, 'a, 'b> Extend<Value<'gc>> for &'b mut Stack<'gc, 'a> {
143 fn extend<T: IntoIterator<Item = Value<'gc>>>(&mut self, iter: T) {
144 self.values.extend(iter);
145 }
146}
147
148impl<'gc: 'b, 'a, 'b> Extend<&'a Value<'gc>> for Stack<'gc, 'a> {
149 fn extend<T: IntoIterator<Item = &'a Value<'gc>>>(&mut self, iter: T) {
150 self.values.extend(iter);
151 }
152}
153
154impl<'gc: 'b, 'a, 'b, 'c> Extend<&'b Value<'gc>> for &'c mut Stack<'gc, 'a> {
155 fn extend<T: IntoIterator<Item = &'b Value<'gc>>>(&mut self, iter: T) {
156 self.values.extend(iter);
157 }
158}
159
160impl<'gc, 'a, I: SliceIndex<[Value<'gc>]>> Index<I> for Stack<'gc, 'a> {
161 type Output = <Vec<Value<'gc>> as Index<I>>::Output;
162
163 fn index(&self, index: I) -> &Self::Output {
164 &self.values[self.bottom..][index]
165 }
166}
167
168impl<'gc, 'a, I: SliceIndex<[Value<'gc>]>> IndexMut<I> for Stack<'gc, 'a> {
169 fn index_mut(&mut self, index: I) -> &mut Self::Output {
170 &mut self.values[self.bottom..][index]
171 }
172}