lending_library/
iter.rs

1/* Notice
2iter.rs: lending-library
3
4Copyright 2018 Thomas Bytheway <thomas.bytheway@cl.cam.ac.uk>
5
6This file is part of the lending-library open-source project: github.com/harkonenbade/lending-library;
7Its licensing is governed by the LICENSE file at the root of the project.
8*/
9
10//! Various iterator structs for `LendingLibrary`
11
12use super::{LendingLibrary, State};
13use std::{hash::Hash, sync::atomic::Ordering};
14
15/// An iterator over the key/value pairs of a `LendingLibrary`
16pub struct Iter<'a, K: 'a, V: 'a> {
17    iter: Box<Iterator<Item = (&'a K, &'a V)> + 'a>,
18}
19
20impl<'a, K, V> Iterator for Iter<'a, K, V> {
21    type Item = (&'a K, &'a V);
22    fn next(&mut self) -> Option<Self::Item> {
23        self.iter.next()
24    }
25}
26
27/// A mutable iterator over the key/value pairs of a `LendingLibrary`
28pub struct IterMut<'a, K: 'a, V: 'a> {
29    iter: Box<Iterator<Item = (&'a K, &'a mut V)> + 'a>,
30}
31
32impl<'a, K, V> Iterator for IterMut<'a, K, V> {
33    type Item = (&'a K, &'a mut V);
34    fn next(&mut self) -> Option<Self::Item> {
35        self.iter.next()
36    }
37}
38
39/// An owning iterator over the key/value pairs of a `LendingLibrary`
40pub struct IntoIter<K, V> {
41    inner: Vec<(K, V)>,
42}
43
44impl<'a, K, V> Iterator for IntoIter<K, V> {
45    type Item = (K, V);
46    fn next(&mut self) -> Option<Self::Item> {
47        if self.inner.is_empty() {
48            None
49        } else {
50            Some(self.inner.remove(0))
51        }
52    }
53}
54
55impl<'a, K, V> IntoIterator for &'a LendingLibrary<K, V>
56where
57    K: Hash,
58{
59    type Item = (&'a K, &'a V);
60    type IntoIter = Iter<'a, K, V>;
61    fn into_iter(self) -> Self::IntoIter {
62        Iter {
63            iter: Box::new(self.store.iter().map(|(_h, v)| match *v {
64                State::Present(ref k, ref v) => (k, v),
65                _ => panic!("Trying to iterate over a store with loaned items."),
66            })),
67        }
68    }
69}
70
71impl<'a, K, V> IntoIterator for &'a mut LendingLibrary<K, V>
72where
73    K: Hash,
74{
75    type Item = (&'a K, &'a mut V);
76    type IntoIter = IterMut<'a, K, V>;
77    fn into_iter(self) -> Self::IntoIter {
78        IterMut {
79            iter: Box::new(self.store.iter_mut().map(|(_h, v)| match *v {
80                State::Present(ref k, ref mut v) => (k, v),
81                _ => panic!("Trying to iterate over a store with loaned items."),
82            })),
83        }
84    }
85}
86
87impl<K, V> IntoIterator for LendingLibrary<K, V>
88where
89    K: Hash,
90{
91    type Item = (K, V);
92    type IntoIter = IntoIter<K, V>;
93    fn into_iter(mut self) -> Self::IntoIter {
94        if self.outstanding.load(Ordering::SeqCst) != 0 {
95            panic!("Trying to iterate over a store with loaned items.")
96        }
97        IntoIter {
98            inner: self
99                .store
100                .drain()
101                .map(|(_h, v)| match v {
102                    State::Present(k, v) => (k, v),
103                    _ => unreachable!(),
104                })
105                .collect::<Vec<_>>(),
106        }
107    }
108}
109
110impl<K, V> Extend<(K, V)> for LendingLibrary<K, V>
111where
112    K: Hash,
113{
114    fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
115        for (k, v) in iter {
116            self.insert(k, v);
117        }
118    }
119}