stdlib_rs/collections/
second.rs1use std::mem;
2
3pub struct List {
4 head: Link,
5}
6
7enum Link {
8 Empty,
9 More(Box<Node>),
10}
11
12struct Node {
13 elem: i32,
14 next: Link,
15}
16
17impl Default for List {
18 fn default() -> Self {
19 Self::new()
20 }
21}
22
23impl List {
24 pub fn new() -> Self {
25 List { head: Link::Empty }
26 }
27
28 pub fn push(&mut self, elem: i32) {
29 let new_node = Box::new(Node {
30 elem,
31 next: mem::replace(&mut self.head, Link::Empty),
32 });
33 self.head = Link::More(new_node);
34 }
35
36 pub fn pop(&mut self) -> Option<i32> {
37 match mem::replace(&mut self.head, Link::Empty) {
38 Link::Empty => None,
39 Link::More(node) => {
40 self.head = node.next;
41 Some(node.elem)
42 }
43 }
44 }
45}
46
47impl Drop for List {
48 fn drop(&mut self) {
49 let mut cur_link = mem::replace(&mut self.head, Link::Empty);
50 while let Link::More(mut boxed_node) = cur_link {
51 cur_link = mem::replace(&mut boxed_node.next, Link::Empty);
52 }
53 }
54}
55
56#[cfg(test)]
57mod test {
58 use super::List;
59
60 #[test]
61 fn basics() {
62 let mut list = List::new();
63
64 assert_eq!(list.pop(), None);
66
67 list.push(1);
69 list.push(2);
70 list.push(3);
71
72 assert_eq!(list.pop(), Some(3));
74 assert_eq!(list.pop(), Some(2));
75
76 list.push(4);
78 list.push(5);
79
80 assert_eq!(list.pop(), Some(5));
82 assert_eq!(list.pop(), Some(4));
83
84 assert_eq!(list.pop(), Some(1));
86 assert_eq!(list.pop(), None);
87 }
88}