1use std::{rc::Rc, sync::RwLock};
2
3#[derive(Default)]
4pub enum BounceState {
5 Reverse,
6 #[default]
7 Forward,
8 NoBounce,
9}
10
11pub fn rwlockify<T: Clone>(iter: impl Iterator<Item = T>) -> impl Iterator<Item = Rc<RwLock<T>>> {
13 iter.map(|x| Rc::new(RwLock::new(x.to_owned())))
14}
15
16pub fn unrwlockify<T: Clone>(iter: impl Iterator<Item = Rc<RwLock<T>>>) -> impl Iterator<Item = T> {
18 iter.map(|x| x.read().expect("Failed to read RWlock").to_owned())
19}
20
21pub struct BounceIterLockedMut<T> {
22 collection: Vec<Rc<RwLock<T>>>,
23 index: usize,
24 bounce_state: BounceState,
25}
26
27impl<T> BounceIterLockedMut<T> {
31 pub fn reset(&mut self) {
32 self.index = 0;
33 }
34 pub fn reset_rev(&mut self) {
35 self.index = self.collection.len() - 1;
36 }
37 pub fn new(collection: Vec<Rc<RwLock<T>>>) -> Self {
38 Self {
39 collection,
40 index: 0,
41 bounce_state: Default::default(),
42 }
43 }
44 pub fn new_rev(collection: Vec<Rc<RwLock<T>>>) -> Self {
45 let len = collection.len() - 1;
46 Self {
47 collection,
48 index: len,
49 bounce_state: Default::default(),
50 }
51 }
52}
53
54impl<T> Iterator for BounceIterLockedMut<T> {
55 type Item = Rc<RwLock<T>>;
56
57 fn next(&mut self) -> Option<Self::Item> {
58 let len = self.collection.len();
59 if len > 1 {
60 if self.index >= len {
61 self.bounce_state = BounceState::Reverse;
62 self.index = len - 2;
63 } else if self.index == 0 {
64 self.bounce_state = BounceState::Forward;
65 }
66 } else {
67 self.bounce_state = BounceState::NoBounce;
68 }
69 let ret = self.collection.get(self.index).cloned();
70
71 match self.bounce_state {
72 BounceState::Reverse => {
73 self.index -= 1;
74 }
75 BounceState::Forward => {
76 self.index += 1;
77 }
78 BounceState::NoBounce => {}
79 }
80 ret
81 }
82}
83
84#[cfg(test)]
85mod tests {
86
87 use super::*;
88 #[test]
89 fn empty() {
90 let mut data: Vec<i32> = Vec::new();
91 let mut iter = BounceIterLockedMut::new(rwlockify(data.iter()).collect());
92 let expected: Vec<i32> = Vec::new();
93 assert_eq!(
94 *unrwlockify(iter).take(5).map(|x| *x).collect::<Vec<_>>(),
95 expected
96 );
97 }
98 #[test]
99 fn smol() {
100 let mut data = vec![1];
101 let mut iter = BounceIterLockedMut::new(rwlockify(data.iter()).collect());
102 let expected = vec![1, 1, 1, 1, 1];
103 assert_eq!(
104 *unrwlockify(iter).take(5).map(|x| *x).collect::<Vec<_>>(),
105 expected
106 );
107 }
108 #[test]
109 fn basic_test() {
110 let mut data = vec![1, 2, 3, 4, 5];
111 let expected = vec![1, 2, 3, 4, 5, 4, 3, 2, 1, 2, 3, 4, 5];
112 let mut iter = BounceIterLockedMut::new(rwlockify(data.iter()).collect());
113 assert_eq!(
114 *unrwlockify(iter).take(13).map(|x| *x).collect::<Vec<_>>(),
115 expected
116 );
117 }
118 #[test]
119 fn basic_test_rev() {
120 let mut data = vec![1, 2, 3, 4, 5];
121 let expected = vec![5, 4, 3, 2, 1, 2, 3, 4, 5, 4, 3, 2, 1, 2, 3, 4, 5];
122 let mut iter = BounceIterLockedMut::new_rev(rwlockify(data.iter()).collect());
123 assert_eq!(
124 *unrwlockify(iter).take(17).map(|x| *x).collect::<Vec<_>>(),
125 expected
126 );
127 }
128 #[test]
129 fn write() {
130 let ptrs: Vec<_> = rwlockify(vec![1, 2, 3, 4, 5].into_iter()).collect();
131 let expected = vec![2, 4, 6, 8, 10];
132 let mut iter = BounceIterLockedMut::new(ptrs);
133 for _ in 0..5 {
134 let Some(item) = iter.next() else {
135 break;
136 };
137 dbg!(&item);
138 let value = *item.read().unwrap();
139 *item.write().unwrap() = value * 2;
140 dbg!(&item);
141 }
142 iter.reset();
143 let data = unrwlockify(iter).take(5).collect::<Vec<_>>();
144 assert_eq!(data, expected);
145 }
146 #[test]
147 fn write_multiple() {
148 let ptrs: Vec<_> = rwlockify(vec![1, 2, 3, 4, 5].into_iter()).collect();
149 let expected = vec![5, 10, 10, 2, 10];
151 let mut iter = BounceIterLockedMut::new(ptrs).peekable();
152 for _ in 0..5 {
153 let Some(item) = iter.next() else {
154 break;
155 };
156 let peek = iter.peek_mut().unwrap();
158 *peek.write().unwrap() = 5;
159 dbg!(&item);
160 let value = *item.read().unwrap();
161 *item.write().unwrap() = value * 2;
162 dbg!(&item);
163 }
164 let data = unrwlockify(iter).take(5).collect::<Vec<_>>();
165 assert_eq!(data, expected);
166 }
167}