scoped_vec/
lib.rs

1//! A library for scoped `Vec`s, allowing multi-level divergence from
2//! the root element.
3//!
4//! This is useful for monitoring state within a de facto tree where
5//! links to parents aren't necessarily needed. Consumers can keep
6//! references to a specific parent if required and check the values
7//! from the scope of their choosing, parents are free to be dropped if
8//! they're no longer required.
9//!
10//! The full [std::vec::Vec] spec has not yet been implemented but as
11//! the library stabilises, more and more of the `Vec` library will be
12//! supported - however there will be some divergence from the API where
13//! necessary given the structural differences of a `ScopedVec`.
14//!
15//! Example:
16//! ```
17//! # use scoped_vec::ScopedVec;
18//! let mut root = ScopedVec::new();
19//! root.push(3);
20//!
21//! {
22//!     let mut scope1 = root.scope();
23//!     scope1.push(4);
24//!     {
25//!         let mut scope1_scope1 = scope1.scope();
26//!         scope1_scope1.push(5);
27//!     }
28//!
29//!     let mut iter = scope1.iter();
30//!     assert_eq!(iter.next(), Some(&4));
31//!     assert_eq!(iter.next(), Some(&5));
32//!     assert_eq!(iter.next(), None);
33//! }
34//!
35//! {
36//!     let mut scope2 = root.scope();
37//!     scope2.push(6);
38//! }
39//!
40//! let mut iter = root.iter();
41//! assert_eq!(iter.next(), Some(&3));
42//! assert_eq!(iter.next(), Some(&4));
43//! assert_eq!(iter.next(), Some(&5));
44//! assert_eq!(iter.next(), Some(&6));
45//! assert_eq!(iter.next(), None);
46//! ```
47
48use std::sync::{Arc, RwLock, RwLockReadGuard};
49use owning_ref::OwningHandle;
50
51/// A `ScopedVec` instance can either represent the root element or a
52/// divergence of it. Refer to the crate's documentation for usage
53/// examples of the scoped-vec library.
54///
55/// Cloning a `ScopedVec` will result in a reference to the same scope,
56/// and adding a value to one of the cloned instances will result in
57/// the value being added to all instances and available for all the
58/// parent instances to iterate over.
59#[derive(Clone)]
60pub struct ScopedVec<T: Clone> {
61    inner: Arc<RwLock<Vec<T>>>,
62    children: Arc<RwLock<Vec<ScopedVec<T>>>>,
63}
64
65impl<T: Clone> ScopedVec<T> {
66    pub fn new() -> Self {
67        Self {
68            inner: Arc::new(RwLock::default()),
69            children: Arc::new(RwLock::default())
70        }
71    }
72
73    /// Create a new `ScopedVec` as a child of this one.
74    pub fn scope(&mut self) -> ScopedVec<T> {
75        let new = ScopedVec::new();
76        //           .get_mut()?
77        self.children.write().unwrap().push(new.clone());
78        new
79    }
80
81    pub fn push(&mut self, val: T) {
82        //        .get_mut()?
83        self.inner.write().unwrap().push(val);
84    }
85
86    pub fn iter(&self) -> ScopedVecIterator<T> {
87        ScopedVecIterator::new(self)
88    }
89}
90
91impl<T: Clone + PartialEq> ScopedVec<T> {
92    pub fn contains(&self, val: &T) -> bool {
93        self.iter().any(|f| *f == *val)
94    }
95}
96
97pub struct ScopedVecGuardHolder<'a, T: Clone> {
98    inner: RwLockReadGuard<'a, Vec<T>>,
99    children: RwLockReadGuard<'a, Vec<ScopedVec<T>>>,
100}
101
102pub struct ScopedVecIterator<'a, T: Clone> {
103    iterator: OwningHandle<Box<ScopedVecGuardHolder<'a, T>>, Box<dyn Iterator<Item = &'a T> + 'a>>,
104}
105impl<'a, T: Clone> ScopedVecIterator<'a, T> {
106    fn new(vec: &'a ScopedVec<T>) -> Self {
107        Self {
108            iterator: OwningHandle::new_with_fn(
109                Box::new(ScopedVecGuardHolder {
110                    inner: vec.inner.read().unwrap(),
111                    children: vec.children.read().unwrap()
112                }),
113                |g| {
114                    // the value behind the raw pointer `g` is boxed, so we're safe to dereference
115                    let guards = unsafe { &*g };
116
117                    Box::new(guards.inner.iter()
118                        .chain(
119                            guards.children.iter()
120                                .map(ScopedVec::iter)
121                                .flatten()
122                        )) as Box<dyn Iterator<Item = &'a T>>
123                }
124            )
125        }
126    }
127}
128impl<'a, T: Clone> Iterator for ScopedVecIterator<'a, T> {
129    type Item = &'a T;
130
131    fn next(&mut self) -> Option<Self::Item> {
132        self.iterator.next()
133    }
134}
135
136#[cfg(test)]
137mod tests {
138    use crate::ScopedVec;
139
140    #[test]
141    fn unscoped_standard() {
142        let mut root = ScopedVec::new();
143        root.push(3);
144        let mut iter = root.iter();
145        assert_eq!(iter.next(), Some(&3));
146        assert_eq!(iter.next(), None);
147    }
148
149    #[test]
150    fn scoped_cant_read_root() {
151        let mut root = ScopedVec::new();
152        root.push(3);
153
154        let scoped = root.scope();
155        let mut iter = scoped.iter();
156        assert_eq!(iter.next(), None);
157    }
158
159    #[test]
160    fn root_can_read_scoped() {
161        let mut root = ScopedVec::new();
162        root.push(3);
163
164        let mut scoped = root.scope();
165        scoped.push(4);
166
167        let mut iter = root.iter();
168        assert_eq!(iter.next(), Some(&3));
169        assert_eq!(iter.next(), Some(&4));
170        assert_eq!(iter.next(), None);
171    }
172
173    #[test]
174    fn root_can_read_nested_scoped() {
175        let mut root = ScopedVec::new();
176        root.push(3);
177
178        let mut scoped = root.scope();
179        scoped.push(4);
180
181        let mut nested_scoped = scoped.scope();
182        nested_scoped.push(5);
183
184        let mut iter = root.iter();
185        assert_eq!(iter.next(), Some(&3));
186        assert_eq!(iter.next(), Some(&4));
187        assert_eq!(iter.next(), Some(&5));
188        assert_eq!(iter.next(), None);
189    }
190
191    #[test]
192    fn scoped_can_read_nested_scoped() {
193        let mut root = ScopedVec::new();
194        root.push(3);
195
196        let mut scoped = root.scope();
197        scoped.push(4);
198
199        let mut nested_scoped = scoped.scope();
200        nested_scoped.push(5);
201
202        let mut iter = scoped.iter();
203        assert_eq!(iter.next(), Some(&4));
204        assert_eq!(iter.next(), Some(&5));
205        assert_eq!(iter.next(), None);
206    }
207
208    #[test]
209    fn nested_scoped_cant_read_backwards() {
210        let mut root = ScopedVec::new();
211        root.push(3);
212
213        let mut scoped = root.scope();
214        scoped.push(4);
215
216        let mut nested_scoped = scoped.scope();
217        nested_scoped.push(5);
218
219        let mut iter = nested_scoped.iter();
220        assert_eq!(iter.next(), Some(&5));
221        assert_eq!(iter.next(), None);
222    }
223
224    #[test]
225    fn can_drop_scopes() {
226        let mut root = ScopedVec::new();
227        root.push(3);
228
229        let mut scoped = root.scope();
230        scoped.push(4);
231
232        drop(root);
233
234        let mut nested_scoped = scoped.scope();
235        nested_scoped.push(5);
236
237        {
238            let mut iter = scoped.iter();
239            assert_eq!(iter.next(), Some(&4));
240            assert_eq!(iter.next(), Some(&5));
241            assert_eq!(iter.next(), None);
242        }
243
244        drop(scoped);
245
246        {
247            let mut iter = nested_scoped.iter();
248            assert_eq!(iter.next(), Some(&5));
249            assert_eq!(iter.next(), None);
250        }
251    }
252
253    #[test]
254    fn diverged_scopes_can_be_read() {
255        let mut root = ScopedVec::new();
256        root.push(3);
257
258        let mut scoped = root.scope();
259        scoped.push(4);
260
261        let mut nested_scoped1 = scoped.scope();
262        nested_scoped1.push(5);
263
264        let mut nested_scoped2 = scoped.scope();
265        nested_scoped2.push(6);
266
267        let mut iter = root.iter();
268        assert_eq!(iter.next(), Some(&3));
269        assert_eq!(iter.next(), Some(&4));
270        assert_eq!(iter.next(), Some(&5));
271        assert_eq!(iter.next(), Some(&6));
272        assert_eq!(iter.next(), None);
273    }
274
275    #[test]
276    fn diverged_adjacent_scopes_cant_interact() {
277        let mut root = ScopedVec::new();
278        root.push(3);
279
280        let mut scoped1 = root.scope();
281        scoped1.push(4);
282
283        let mut scoped2 = root.scope();
284        scoped2.push(5);
285
286        let mut iter = scoped1.iter();
287        assert_eq!(iter.next(), Some(&4));
288        assert_eq!(iter.next(), None);
289
290        let mut iter = scoped2.iter();
291        assert_eq!(iter.next(), Some(&5));
292        assert_eq!(iter.next(), None);
293    }
294}