Skip to content

Commit c2ce422

Browse files
committed
List has clear and drain
1 parent 9839570 commit c2ce422

File tree

2 files changed

+63
-4
lines changed

2 files changed

+63
-4
lines changed

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* `attributes.value_as::<T>` is now available on `Attributes`
55
* Performance improvements
66
* New template function: `len`
7+
* `List<T>` now has `clear` and `retain`
78
* 0.2.11
89
* FEATURE: ranges
910
* `padding` function

anathema-state/src/value/list.rs

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ impl<T: State> Default for List<T> {
5858
/// list.push(123);
5959
/// ```
6060
impl<T: State> Value<List<T>> {
61+
// This does not trigger a change but still gives mutable access
62+
// to the underlying list.
6163
fn with_mut<F, U>(&mut self, f: F) -> U
6264
where
6365
F: FnOnce(&mut List<T>) -> U,
@@ -75,11 +77,37 @@ impl<T: State> Value<List<T>> {
7577
ret_val
7678
}
7779

80+
/// Create an empty list
7881
pub fn empty() -> Self {
7982
let list = List { inner: VecDeque::new() };
8083
Value::new(list)
8184
}
8285

86+
/// Clear the list
87+
pub fn clear(&mut self) {
88+
self.set(List::empty());
89+
}
90+
91+
/// Retain all values that matches the predicate
92+
pub fn retain<F>(&mut self, mut f: F)
93+
where
94+
F: FnMut(&Value<T>) -> bool,
95+
{
96+
let key = self.key;
97+
let mut index = 0;
98+
self.with_mut(|list| {
99+
list.inner.retain(|value| {
100+
let retain = f(value);
101+
if !retain {
102+
changed(key, Change::Removed(index));
103+
}
104+
index += 1;
105+
retain
106+
});
107+
});
108+
}
109+
110+
/// Get a reference to a value
83111
pub fn get<'a>(&'a self, index: usize) -> Option<Shared<'a, T>> {
84112
let list = &*self.to_ref();
85113
let value = list.get(index)?;
@@ -90,6 +118,7 @@ impl<T: State> Value<List<T>> {
90118
Some(shared)
91119
}
92120

121+
/// Get a mutable reference to a value
93122
pub fn get_mut<'a>(&'a mut self, index: usize) -> Option<Unique<'a, T>> {
94123
let list = &*self.to_ref();
95124
let value = list.get(index)?;
@@ -184,10 +213,7 @@ impl<T: State> Value<List<T>> {
184213
});
185214
}
186215

187-
pub fn len(&self) -> usize {
188-
self.to_ref().len()
189-
}
190-
216+
/// Merge the list with another list.
191217
pub fn merge(&mut self, other: &mut Self) {
192218
while let Some(value) = other.pop_front() {
193219
let index = self.with_mut(|list| {
@@ -200,6 +226,12 @@ impl<T: State> Value<List<T>> {
200226
}
201227
}
202228

229+
/// Return the length of the list
230+
pub fn len(&self) -> usize {
231+
self.to_ref().len()
232+
}
233+
234+
/// Returns true if the list is empty
203235
pub fn is_empty(&self) -> bool {
204236
self.to_ref().is_empty()
205237
}
@@ -303,6 +335,32 @@ mod test {
303335
assert_eq!(*front.unwrap().to_ref(), 1);
304336
}
305337

338+
#[test]
339+
fn notify_clear() {
340+
let mut list = Value::new(List::<u32>::empty());
341+
list.reference().subscribe(Subscriber::ZERO);
342+
list.clear();
343+
344+
let change = drain_changes().remove(0);
345+
assert!(matches!(change, (_, Change::Changed)));
346+
}
347+
348+
#[test]
349+
fn notify_retain() {
350+
let mut list = Value::new(List::<u32>::empty());
351+
list.push_back(1);
352+
list.push_back(2);
353+
list.push_back(3);
354+
355+
list.reference().subscribe(Subscriber::ZERO);
356+
357+
list.retain(|val| *val.to_ref() == 1);
358+
359+
let mut changes = drain_changes();
360+
assert!(matches!(changes.remove(0), (_, Change::Removed(2))));
361+
assert!(matches!(changes.remove(0), (_, Change::Removed(1))));
362+
}
363+
306364
#[test]
307365
fn notify_pop_back() {
308366
let mut list = Value::new(List::<u32>::empty());

0 commit comments

Comments
 (0)