cljrs_value/collections/
vector.rs1use crate::Value;
2
3#[derive(Debug, Clone)]
12pub struct PersistentVector {
13 inner: rpds::VectorSync<Value>,
14 is_map_entry: bool,
15}
16
17impl PersistentVector {
18 pub fn empty() -> Self {
19 Self {
20 inner: rpds::VectorSync::new_sync(),
21 is_map_entry: false,
22 }
23 }
24
25 pub fn from_vector(vector: rpds::VectorSync<Value>) -> Self {
26 Self {
27 inner: vector,
28 is_map_entry: false,
29 }
30 }
31
32 pub fn map_entry(key: Value, val: Value) -> Self {
34 let mut inner = rpds::VectorSync::new_sync();
35 inner = inner.push_back(key);
36 inner = inner.push_back(val);
37 Self {
38 inner,
39 is_map_entry: true,
40 }
41 }
42
43 pub fn is_map_entry(&self) -> bool {
45 self.is_map_entry
46 }
47
48 pub fn count(&self) -> usize {
49 self.inner.len()
50 }
51
52 pub fn is_empty(&self) -> bool {
53 self.inner.is_empty()
54 }
55
56 pub fn conj(&self, val: Value) -> Self {
58 Self {
59 inner: self.inner.push_back(val),
60 is_map_entry: false,
61 }
62 }
63
64 pub fn nth(&self, idx: usize) -> Option<&Value> {
66 self.inner.get(idx)
67 }
68
69 pub fn peek(&self) -> Option<&Value> {
71 self.inner.last()
72 }
73
74 pub fn assoc_nth(&self, idx: usize, val: Value) -> Option<Self> {
76 if idx == self.inner.len() {
77 Some(self.conj(val))
78 } else {
79 Some(Self {
80 inner: self.inner.set(idx, val)?,
81 is_map_entry: false,
82 })
83 }
84 }
85
86 pub fn pop(&self) -> Option<Self> {
88 Some(Self {
89 inner: self.inner.drop_last()?,
90 is_map_entry: false,
91 })
92 }
93
94 pub fn iter(&self) -> impl Iterator<Item = &Value> {
96 self.inner.iter()
97 }
98
99 pub fn inner(&self) -> &rpds::VectorSync<Value> {
100 &self.inner
101 }
102}
103
104impl std::iter::FromIterator<Value> for PersistentVector {
105 fn from_iter<I: IntoIterator<Item = Value>>(iter: I) -> Self {
106 let mut v = rpds::VectorSync::new_sync();
107 for item in iter {
108 v = v.push_back(item);
109 }
110 Self {
111 inner: v,
112 is_map_entry: false,
113 }
114 }
115}
116
117impl PartialEq for PersistentVector {
118 fn eq(&self, other: &Self) -> bool {
119 if self.inner.len() != other.inner.len() {
120 return false;
121 }
122 self.iter().zip(other.iter()).all(|(a, b)| a == b)
123 }
124}
125
126impl cljrs_gc::Trace for PersistentVector {
127 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
128 for v in self.inner.iter() {
129 v.trace(visitor);
130 }
131 }
132
133 fn gc_size_extra(&self) -> usize {
134 let n = self.inner.len();
136 n * (24 + std::mem::size_of::<Value>())
137 }
138}
139
140#[cfg(test)]
141mod tests {
142 use super::*;
143 use crate::Value;
144
145 fn int(n: i64) -> Value {
146 Value::Long(n)
147 }
148
149 #[test]
150 fn test_empty() {
151 let v = PersistentVector::empty();
152 assert!(v.is_empty());
153 assert_eq!(v.count(), 0);
154 assert!(v.nth(0).is_none());
155 }
156
157 #[test]
158 fn test_conj_small() {
159 let v = PersistentVector::from_iter([int(1), int(2), int(3)]);
160 assert_eq!(v.count(), 3);
161 assert_eq!(v.nth(0), Some(&int(1)));
162 assert_eq!(v.nth(2), Some(&int(3)));
163 }
164
165 #[test]
166 fn test_conj_forces_tail_flush() {
167 let v = PersistentVector::from_iter((0..33).map(int));
168 assert_eq!(v.count(), 33);
169 for i in 0..33 {
170 assert_eq!(v.nth(i), Some(&int(i as i64)), "nth({i}) wrong");
171 }
172 }
173
174 #[test]
175 fn test_large() {
176 let n = 1025;
177 let v = PersistentVector::from_iter((0..n).map(|i| int(i as i64)));
178 assert_eq!(v.count(), n);
179 for i in 0..n {
180 assert_eq!(v.nth(i), Some(&int(i as i64)));
181 }
182 }
183
184 #[test]
185 fn test_peek() {
186 let v = PersistentVector::from_iter([int(1), int(2), int(3)]);
187 assert_eq!(v.peek(), Some(&int(3)));
188 }
189
190 #[test]
191 fn test_assoc_nth() {
192 let v = PersistentVector::from_iter([int(1), int(2), int(3)]);
193 let v2 = v.assoc_nth(1, int(99)).unwrap();
194 assert_eq!(v2.nth(0), Some(&int(1)));
195 assert_eq!(v2.nth(1), Some(&int(99)));
196 assert_eq!(v2.nth(2), Some(&int(3)));
197 assert_eq!(v.nth(1), Some(&int(2)));
199 }
200
201 #[test]
202 fn test_pop() {
203 let v = PersistentVector::from_iter([int(1), int(2), int(3)]);
204 let v2 = v.pop().unwrap();
205 assert_eq!(v2.count(), 2);
206 assert_eq!(v2.nth(0), Some(&int(1)));
207 assert_eq!(v2.nth(1), Some(&int(2)));
208 }
209
210 #[test]
211 fn test_equality() {
212 let a = PersistentVector::from_iter([int(1), int(2)]);
213 let b = PersistentVector::from_iter([int(1), int(2)]);
214 let c = PersistentVector::from_iter([int(1), int(3)]);
215 assert_eq!(a, b);
216 assert_ne!(a, c);
217 }
218
219 #[test]
220 fn test_map_entry_flag() {
221 let e = PersistentVector::map_entry(int(1), int(2));
222 assert!(e.is_map_entry());
223 assert_eq!(e.count(), 2);
224 assert_eq!(e.nth(0), Some(&int(1)));
225 assert_eq!(e.nth(1), Some(&int(2)));
226 assert_eq!(e, PersistentVector::from_iter([int(1), int(2)]));
228 assert!(!PersistentVector::from_iter([int(1), int(2)]).is_map_entry());
230 assert!(!e.conj(int(3)).is_map_entry());
232 assert!(!e.assoc_nth(0, int(9)).unwrap().is_map_entry());
233 assert!(!e.pop().unwrap().is_map_entry());
234 }
235
236 #[test]
237 fn test_iter_order() {
238 let v = PersistentVector::from_iter((0..10).map(|i| int(i as i64)));
239 let items: Vec<_> = v.iter().cloned().collect();
240 assert_eq!(items, (0..10).map(|i| int(i as i64)).collect::<Vec<_>>());
241 }
242}