rt_lists/
first.rs

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