cljrs_value/collections/
vector.rs1use crate::Value;
2
3#[derive(Debug, Clone)]
5pub struct PersistentVector {
6 inner: rpds::VectorSync<Value>,
7}
8
9impl PersistentVector {
10 pub fn empty() -> Self {
11 Self {
12 inner: rpds::VectorSync::new_sync(),
13 }
14 }
15
16 pub fn from_vector(vector: rpds::VectorSync<Value>) -> Self {
17 Self { inner: vector }
18 }
19
20 pub fn count(&self) -> usize {
21 self.inner.len()
22 }
23
24 pub fn is_empty(&self) -> bool {
25 self.inner.is_empty()
26 }
27
28 pub fn conj(&self, val: Value) -> Self {
30 Self {
31 inner: self.inner.push_back(val),
32 }
33 }
34
35 pub fn nth(&self, idx: usize) -> Option<&Value> {
37 self.inner.get(idx)
38 }
39
40 pub fn peek(&self) -> Option<&Value> {
42 self.inner.last()
43 }
44
45 pub fn assoc_nth(&self, idx: usize, val: Value) -> Option<Self> {
47 if idx == self.inner.len() {
48 Some(self.conj(val))
49 } else {
50 Some(Self {
51 inner: self.inner.set(idx, val)?,
52 })
53 }
54 }
55
56 pub fn pop(&self) -> Option<Self> {
58 Some(Self {
59 inner: self.inner.drop_last()?,
60 })
61 }
62
63 pub fn iter(&self) -> impl Iterator<Item = &Value> {
65 self.inner.iter()
66 }
67
68 pub fn inner(&self) -> &rpds::VectorSync<Value> {
69 &self.inner
70 }
71}
72
73impl std::iter::FromIterator<Value> for PersistentVector {
74 fn from_iter<I: IntoIterator<Item = Value>>(iter: I) -> Self {
75 let mut v = rpds::VectorSync::new_sync();
76 for item in iter {
77 v = v.push_back(item);
78 }
79 Self { inner: v }
80 }
81}
82
83impl PartialEq for PersistentVector {
84 fn eq(&self, other: &Self) -> bool {
85 if self.inner.len() != other.inner.len() {
86 return false;
87 }
88 self.iter().zip(other.iter()).all(|(a, b)| a == b)
89 }
90}
91
92impl cljrs_gc::Trace for PersistentVector {
93 fn trace(&self, visitor: &mut cljrs_gc::MarkVisitor) {
94 for v in self.inner.iter() {
95 v.trace(visitor);
96 }
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103 use crate::Value;
104
105 fn int(n: i64) -> Value {
106 Value::Long(n)
107 }
108
109 #[test]
110 fn test_empty() {
111 let v = PersistentVector::empty();
112 assert!(v.is_empty());
113 assert_eq!(v.count(), 0);
114 assert!(v.nth(0).is_none());
115 }
116
117 #[test]
118 fn test_conj_small() {
119 let v = PersistentVector::from_iter([int(1), int(2), int(3)]);
120 assert_eq!(v.count(), 3);
121 assert_eq!(v.nth(0), Some(&int(1)));
122 assert_eq!(v.nth(2), Some(&int(3)));
123 }
124
125 #[test]
126 fn test_conj_forces_tail_flush() {
127 let v = PersistentVector::from_iter((0..33).map(int));
128 assert_eq!(v.count(), 33);
129 for i in 0..33 {
130 assert_eq!(v.nth(i), Some(&int(i as i64)), "nth({i}) wrong");
131 }
132 }
133
134 #[test]
135 fn test_large() {
136 let n = 1025;
137 let v = PersistentVector::from_iter((0..n).map(|i| int(i as i64)));
138 assert_eq!(v.count(), n);
139 for i in 0..n {
140 assert_eq!(v.nth(i), Some(&int(i as i64)));
141 }
142 }
143
144 #[test]
145 fn test_peek() {
146 let v = PersistentVector::from_iter([int(1), int(2), int(3)]);
147 assert_eq!(v.peek(), Some(&int(3)));
148 }
149
150 #[test]
151 fn test_assoc_nth() {
152 let v = PersistentVector::from_iter([int(1), int(2), int(3)]);
153 let v2 = v.assoc_nth(1, int(99)).unwrap();
154 assert_eq!(v2.nth(0), Some(&int(1)));
155 assert_eq!(v2.nth(1), Some(&int(99)));
156 assert_eq!(v2.nth(2), Some(&int(3)));
157 assert_eq!(v.nth(1), Some(&int(2)));
159 }
160
161 #[test]
162 fn test_pop() {
163 let v = PersistentVector::from_iter([int(1), int(2), int(3)]);
164 let v2 = v.pop().unwrap();
165 assert_eq!(v2.count(), 2);
166 assert_eq!(v2.nth(0), Some(&int(1)));
167 assert_eq!(v2.nth(1), Some(&int(2)));
168 }
169
170 #[test]
171 fn test_equality() {
172 let a = PersistentVector::from_iter([int(1), int(2)]);
173 let b = PersistentVector::from_iter([int(1), int(2)]);
174 let c = PersistentVector::from_iter([int(1), int(3)]);
175 assert_eq!(a, b);
176 assert_ne!(a, c);
177 }
178
179 #[test]
180 fn test_iter_order() {
181 let v = PersistentVector::from_iter((0..10).map(|i| int(i as i64)));
182 let items: Vec<_> = v.iter().cloned().collect();
183 assert_eq!(items, (0..10).map(|i| int(i as i64)).collect::<Vec<_>>());
184 }
185}