Skip to main content

anathema_state/value/
list.rs

1//! The reason the `List<T>` has the insert and remove implementation on `Value<List<T>>` instead of
2//! having it directly on `List<T>`, unlike `Map<T>` is because the list generates different
3//! changes and are used with for-loops, unlike the map.
4use std::collections::VecDeque;
5use std::ops::DerefMut;
6
7use super::{Shared, Type, Unique, Value};
8use crate::states::{AnyList, State};
9use crate::store::changed;
10use crate::store::values::{get_unique, try_make_shared};
11use crate::{Change, PendingValue};
12
13#[derive(Debug)]
14pub struct List<T> {
15    inner: VecDeque<Value<T>>,
16}
17
18impl<T: State> List<T> {
19    pub const fn empty() -> Self {
20        Self { inner: VecDeque::new() }
21    }
22
23    pub fn get(&self, index: usize) -> Option<&Value<T>> {
24        self.inner.get(index)
25    }
26
27    pub fn get_mut(&mut self, index: usize) -> Option<&mut Value<T>> {
28        self.inner.get_mut(index)
29    }
30
31    pub fn iter(&self) -> impl Iterator<Item = &Value<T>> {
32        self.inner.iter()
33    }
34
35    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Value<T>> {
36        self.inner.iter_mut()
37    }
38
39    pub fn len(&self) -> usize {
40        self.inner.len()
41    }
42
43    pub fn is_empty(&self) -> bool {
44        self.inner.is_empty()
45    }
46}
47
48impl<T: State> Default for List<T> {
49    fn default() -> Self {
50        Self { inner: VecDeque::new() }
51    }
52}
53
54/// A `List` of values.
55/// ```
56/// # use anathema_state::{Value, List};
57/// let mut list: Value<List<u32>> = List::empty().into();
58/// list.push(123);
59/// ```
60impl<T: State> Value<List<T>> {
61    fn with_mut<F, U>(&mut self, f: F) -> U
62    where
63        F: FnOnce(&mut List<T>) -> U,
64    {
65        let mut inner = get_unique(self.key.owned());
66
67        let list: &mut dyn State = inner.val.deref_mut();
68        let list: &mut dyn std::any::Any = list;
69        let list: &mut List<T> = list.downcast_mut().expect("the type should never change");
70
71        let ret_val = f(list);
72
73        crate::store::values::return_owned(self.key.owned(), inner);
74
75        ret_val
76    }
77
78    pub fn empty() -> Self {
79        let list = List { inner: VecDeque::new() };
80        Value::new(list)
81    }
82
83    pub fn get<'a>(&'a self, index: usize) -> Option<Shared<'a, T>> {
84        let list = &*self.to_ref();
85        let value = list.get(index)?;
86        let key = value.key;
87
88        let (key, value) = try_make_shared(key.owned())?;
89        let shared = Shared::new(key, value);
90        Some(shared)
91    }
92
93    pub fn get_mut<'a>(&'a mut self, index: usize) -> Option<Unique<'a, T>> {
94        let list = &*self.to_ref();
95        let value = list.get(index)?;
96
97        let key = value.key;
98        let value = Unique {
99            value: Some(get_unique(key.owned())),
100            key,
101            _p: std::marker::PhantomData,
102        };
103        Some(value)
104    }
105
106    /// Push a value to the list
107    pub fn push(&mut self, value: T) {
108        self.push_back(value)
109    }
110
111    /// Push a value to the back of the list
112    pub fn push_back(&mut self, value: T) {
113        let value = Value::new(value);
114
115        let index = self.with_mut(|list| {
116            let index = list.len();
117            list.inner.push_back(value);
118            index as u32
119        });
120
121        changed(self.key, Change::Inserted(index));
122    }
123
124    /// Push a value to the front of the list
125    pub fn push_front(&mut self, value: impl Into<Value<T>>) {
126        let value = value.into();
127        self.with_mut(|list| list.inner.push_front(value));
128        changed(self.key, Change::Inserted(0));
129    }
130
131    /// Insert a value at a given index.
132    ///
133    /// # Panics
134    ///
135    /// Will panic if the index is out of bounds
136    pub fn insert(&mut self, index: usize, value: impl Into<Value<T>>) {
137        let value = value.into();
138        self.with_mut(|list| list.inner.insert(index, value));
139        changed(self.key, Change::Inserted(index as u32));
140    }
141
142    /// Remove a value from the list.
143    /// If the value isn't in the list `None` is returned.
144    pub fn remove(&mut self, index: usize) -> Option<Value<T>> {
145        let value = self.with_mut(|list| list.inner.remove(index));
146        changed(self.key, Change::Removed(index as u32));
147        value
148    }
149
150    /// Pop a value from the front of the list
151    pub fn pop_front(&mut self) -> Option<Value<T>> {
152        let value = self.with_mut(|list| list.inner.pop_front());
153        if value.is_some() {
154            changed(self.key, Change::Removed(0));
155        }
156        value
157    }
158
159    /// Pop a value from the back of the list
160    pub fn pop_back(&mut self) -> Option<Value<T>> {
161        let value = self.with_mut(|list| list.inner.pop_back());
162        if value.is_some() {
163            let index = self.len();
164            changed(self.key, Change::Removed(index as u32));
165        }
166        value
167    }
168
169    /// Alias for `pop_back`
170    pub fn pop(&mut self) -> Option<Value<T>> {
171        self.pop_back()
172    }
173
174    /// Calls a closure on each element of the list.
175    /// Each element will be marked as changed.
176    pub fn for_each<F>(&mut self, mut f: F)
177    where
178        F: FnMut(&mut T),
179    {
180        self.with_mut(|list| {
181            list.inner.iter_mut().for_each(|val| {
182                f(&mut *val.to_mut());
183            })
184        });
185    }
186
187    pub fn len(&self) -> usize {
188        self.to_ref().len()
189    }
190
191    pub fn merge(&mut self, other: &mut Self) {
192        while let Some(value) = other.pop_front() {
193            let index = self.with_mut(|list| {
194                let index = list.len();
195                list.inner.push_back(value);
196                index as u32
197            });
198
199            changed(self.key, Change::Inserted(index));
200        }
201    }
202
203    pub fn is_empty(&self) -> bool {
204        self.to_ref().is_empty()
205    }
206}
207
208impl<T: State> AnyList for List<T> {
209    fn lookup(&self, index: usize) -> Option<PendingValue> {
210        self.get(index).map(|val| val.reference())
211    }
212
213    fn len(&self) -> usize {
214        self.inner.len()
215    }
216}
217
218impl<T: State> State for List<T> {
219    fn type_info(&self) -> Type {
220        Type::List
221    }
222
223    fn as_any_list(&self) -> Option<&dyn AnyList> {
224        Some(self)
225    }
226}
227
228impl<T> FromIterator<T> for Value<List<T>>
229where
230    T: State,
231    Value<T>: From<T>,
232{
233    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
234        let inner = iter.into_iter().map(Into::into).collect::<VecDeque<_>>();
235        let list = List { inner };
236        Value::new(list)
237    }
238}
239
240impl<T> FromIterator<T> for List<T>
241where
242    T: State,
243{
244    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
245        let inner = iter.into_iter().map(Into::into).collect::<VecDeque<_>>();
246        List { inner }
247    }
248}
249
250#[cfg(test)]
251mod test {
252
253    use super::*;
254    use crate::Subscriber;
255    use crate::store::testing::drain_changes;
256
257    #[test]
258    fn insert() {
259        let mut list = Value::new(List::empty());
260        list.push_back(1usize);
261
262        list.push_front(0usize);
263        let list = list.to_ref();
264
265        let val = list.get(0).unwrap().to_ref();
266        assert_eq!(*val, 0);
267
268        let val = list.get(1).unwrap().to_ref();
269        assert_eq!(*val, 1);
270    }
271
272    #[test]
273    fn notify_insert() {
274        let mut list = Value::new(List::<u32>::empty());
275        list.reference().subscribe(Subscriber::ZERO);
276        list.push_back(1);
277
278        let (_, change) = drain_changes().remove(0);
279        assert!(matches!(change, Change::Inserted(_)));
280    }
281
282    #[test]
283    fn notify_remove() {
284        let mut list = Value::new(List::<u32>::empty());
285        list.push_back(1);
286        list.reference().subscribe(Subscriber::ZERO);
287        list.remove(0);
288
289        let change = drain_changes().remove(0);
290        assert!(matches!(change, (_, Change::Removed(_))));
291    }
292
293    #[test]
294    fn notify_pop_front() {
295        let mut list = Value::new(List::<u32>::empty());
296        list.push_back(1);
297        list.push_back(2);
298        list.reference().subscribe(Subscriber::ZERO);
299        let front = list.pop_front();
300
301        let change = drain_changes().remove(0);
302        assert!(matches!(change, (_, Change::Removed(0))));
303        assert_eq!(*front.unwrap().to_ref(), 1);
304    }
305
306    #[test]
307    fn notify_pop_back() {
308        let mut list = Value::new(List::<u32>::empty());
309        list.push_back(0);
310        list.push_back(1);
311        list.reference().subscribe(Subscriber::ZERO);
312        list.pop_back();
313
314        let change = drain_changes().remove(0);
315        assert!(matches!(change, (_, Change::Removed(1))));
316    }
317
318    #[test]
319    fn pop_empty_list() {
320        let mut list = Value::new(List::<u32>::empty());
321        list.reference().subscribe(Subscriber::ZERO);
322        list.pop_back();
323        let changes = drain_changes();
324        assert!(changes.is_empty());
325
326        list.pop_front();
327        let changes = drain_changes();
328        assert!(changes.is_empty());
329    }
330}