scopegraphs_prust_lib/
list.rs

1use crate::RefCounter;
2
3enum ListNode<T> {
4    Empty,
5    Value {
6        value: RefCounter<T>,
7        next_node: RefCounter<ListNode<T>>,
8    },
9}
10
11impl<T> Clone for ListNode<T> {
12    fn clone(&self) -> Self {
13        match self {
14            ListNode::Empty => ListNode::Empty,
15            ListNode::Value { value, next_node } => ListNode::Value {
16                value: value.clone(),
17                next_node: next_node.clone(),
18            },
19        }
20    }
21}
22
23impl<T> Clone for List<T> {
24    fn clone(&self) -> Self {
25        List {
26            head: self.head.clone(),
27            len: self.len,
28        }
29    }
30}
31
32pub struct ListIterator<T> {
33    current: RefCounter<ListNode<T>>,
34}
35
36impl<T> Iterator for ListIterator<T> {
37    type Item = RefCounter<T>;
38
39    fn next(&mut self) -> Option<Self::Item> {
40        match self.current.as_ref() {
41            ListNode::Empty => None,
42            ListNode::Value { value, next_node } => {
43                let return_value = value.clone();
44                self.current = next_node.clone();
45                Some(return_value)
46            }
47        }
48    }
49}
50
51pub struct List<T> {
52    head: RefCounter<ListNode<T>>,
53    len: usize,
54}
55
56impl<T> List<T> {
57    pub fn iter(&self) -> ListIterator<T> {
58        ListIterator {
59            current: self.head.clone(),
60        }
61    }
62    pub fn split(&self) -> (List<T>, List<T>) {
63        let mut first = List::<T>::empty();
64        let mut second = List::<T>::empty();
65        let mut current = self.clone();
66        let half = self.length() / 2;
67        let other_half = self.length() - half;
68        for _ in 0..half {
69            let (value_rc, new_list) = current.pop_front_rc().unwrap();
70            first = first.push_front_rc(value_rc);
71            current = new_list;
72        }
73        for _ in 0..other_half {
74            let (value_rc, new_list) = current.pop_front_rc().unwrap();
75            second = second.push_front_rc(value_rc);
76            current = new_list;
77        }
78        (first.reverse(), second.reverse())
79    }
80    pub fn reverse(&self) -> List<T> {
81        let mut node = self.head.clone();
82        let mut last_node = RefCounter::new(ListNode::Empty);
83        while let ListNode::Value { value, next_node } = node.as_ref() {
84            let new_node = ListNode::Value {
85                value: value.clone(),
86                next_node: last_node,
87            };
88            last_node = RefCounter::new(new_node);
89            node = next_node.clone();
90        }
91        List {
92            head: last_node,
93            len: self.len,
94        }
95    }
96    pub fn empty() -> List<T> {
97        List {
98            head: RefCounter::new(ListNode::Empty),
99            len: 0,
100        }
101    }
102    fn push_front_rc(&self, rc_value: RefCounter<T>) -> List<T> {
103        List {
104            head: RefCounter::new(ListNode::Value {
105                value: rc_value,
106                next_node: self.head.clone(),
107            }),
108            len: self.len + 1,
109        }
110    }
111    pub fn push_front(&self, value: T) -> List<T> {
112        self.push_front_rc(RefCounter::new(value))
113    }
114    pub fn is_empty(&self) -> bool {
115        self.length() == 0
116    }
117    pub fn length(&self) -> usize {
118        self.len
119    }
120    pub fn pop_front_rc(&self) -> Option<(RefCounter<T>, List<T>)> {
121        match self.head.as_ref() {
122            ListNode::Empty => Option::None,
123            ListNode::Value {
124                value,
125                ref next_node,
126            } => Option::Some((
127                value.clone(),
128                List {
129                    head: next_node.clone(),
130                    len: self.len - 1,
131                },
132            )),
133        }
134    }
135    pub fn pop_front(&self) -> Option<(&T, List<T>)> {
136        match self.head.as_ref() {
137            ListNode::Empty => Option::None,
138            ListNode::Value {
139                value,
140                ref next_node,
141            } => Option::Some((
142                value,
143                List {
144                    head: next_node.clone(),
145                    len: self.len - 1,
146                },
147            )),
148        }
149    }
150    pub fn front(&self) -> Option<&T> {
151        self.pop_front().map(|(e, _)| e)
152    }
153}
154
155#[cfg(test)]
156mod tests {
157    use super::*;
158
159    #[test]
160    fn test_iter() {
161        let l = List::empty()
162            .push_front(4)
163            .push_front(3)
164            .push_front(2)
165            .push_front(1);
166        let v = [1, 2, 3, 4];
167        for (idx, val) in l.iter().enumerate() {
168            assert_eq!(v[idx], *val);
169        }
170    }
171
172    #[test]
173    fn test_split() {
174        let l = List::empty()
175            .push_front(4)
176            .push_front(3)
177            .push_front(2)
178            .push_front(1);
179        let (a, b) = l.split();
180        assert_eq!(a.length(), 2);
181        assert_eq!(b.length(), 2);
182    }
183
184    #[test]
185    fn test_list() {
186        // Create an empty list and verify its properties.
187        let empty_list = List::empty();
188        assert_eq!(empty_list.length(), 0);
189        assert!(empty_list.is_empty());
190        assert!(empty_list.pop_front().is_none());
191        assert!(empty_list.front().is_none());
192
193        // Push elements and check its properties.
194        let list = empty_list.push_front(123).push_front(987);
195        assert_eq!(list.length(), 2);
196        assert!(!list.is_empty());
197        assert_eq!(list.front(), Some(&987));
198
199        // Pop front and verify the popped element and remaining list.
200        let (popped_element, remaining_list) = list.pop_front().unwrap();
201        assert_eq!(*popped_element, 987);
202        assert_eq!(remaining_list.length(), 1);
203        assert_eq!(remaining_list.front(), Some(&123));
204    }
205
206    #[test]
207    fn test_list_reverse() {
208        let list = List::empty().push_front(1).push_front(2);
209        let reversed_list = list.reverse();
210
211        // Verify that reversed_list indeed contains elements in reverse order
212        let (first_element, list_after_first_pop) = reversed_list.pop_front().unwrap();
213        assert_eq!(*first_element, 1);
214
215        let (second_element, _) = list_after_first_pop.pop_front().unwrap();
216        assert_eq!(*second_element, 2);
217    }
218}