1use crate::linked_list::{LinkedList, LinkedListIndex, LinkedListItem};
2
3pub trait Walker<Context> {
11 type Item;
12 fn walk_next(&mut self, context: Context) -> Option<Self::Item>;
14
15 fn iter(self, context: Context) -> WalkerIter<Self, Context>
17 where
18 Self: Sized,
19 Context: Clone,
20 {
21 WalkerIter {
22 walker: self,
23 context,
24 }
25 }
26}
27
28#[derive(Clone, Debug)]
30pub struct WalkerIter<W, C> {
31 walker: W,
32 context: C,
33}
34
35impl<W, C> WalkerIter<W, C>
36where
37 W: Walker<C>,
38 C: Clone,
39{
40 pub fn context(&self) -> C {
41 self.context.clone()
42 }
43
44 pub fn inner_ref(&self) -> &W {
45 &self.walker
46 }
47
48 pub fn inner_mut(&mut self) -> &mut W {
49 &mut self.walker
50 }
51}
52
53impl<W, C> Iterator for WalkerIter<W, C>
54where
55 W: Walker<C>,
56 C: Clone,
57{
58 type Item = W::Item;
59 fn next(&mut self) -> Option<Self::Item> {
60 self.walker.walk_next(self.context.clone())
61 }
62}
63
64impl<'a, C, W: ?Sized> Walker<C> for &'a mut W
65where
66 W: Walker<C>,
67{
68 type Item = W::Item;
69 fn walk_next(&mut self, context: C) -> Option<Self::Item> {
70 (**self).walk_next(context)
71 }
72}
73
74pub struct LinkedListWalker {
75 current: Option<LinkedListIndex>,
77 reverse: bool,
79}
80
81impl LinkedListWalker {
82 pub fn new<T>(list: &LinkedList<T>, start: LinkedListIndex, reverse: bool) -> Self {
83 Self {
84 current: Some(start),
85 reverse: reverse,
86 }
87 }
88}
89
90impl<T> Walker<&LinkedList<T>> for LinkedListWalker {
91 type Item = LinkedListIndex;
92
93 fn walk_next(&mut self, context: &LinkedList<T>) -> Option<Self::Item> {
98 if let Some(current) = self.current {
99 return if self.reverse {
100 context.get(current).and_then(|item| {
101 self.current = item.prev_index;
102 item.prev_index
103 })
104 } else {
105 context.get(current).and_then(|item| {
106 self.current = item.next_index;
107 item.next_index
108 })
109 };
110 }
111 None
112 }
113}
114
115#[cfg(test)]
134mod tests {
135 use super::*;
136
137 #[test]
138 pub fn test_list_walker() {
139 let mut list = LinkedList::new();
140 list.extend(0..=100);
141 let mut count = 0;
142 let mut walker = LinkedListWalker::new(&list, list.tail.unwrap(), true);
143
144 assert_eq!(list.get(list.head.unwrap()).unwrap().value, 0);
145 assert_eq!(list.get(list.tail.unwrap()).unwrap().value, 100);
146
147 list.tail_mut().unwrap().value = 0;
148 while let Some(index) = walker.walk_next(&list) {
149 count += 1;
150 list.get_mut(index).unwrap().value = count;
151 }
154
155 assert_eq!(count, 100);
156 assert_eq!(list.get(list.head.unwrap()).unwrap().value, 100);
157 assert_eq!(list.get(list.tail.unwrap()).unwrap().value, 0);
158 }
159}