rt_lists/
first.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
pub struct List {
  head: Link,
}

#[allow(dead_code)]
enum Link {
    Empty,
    More(Box<Node>),
}

#[allow(dead_code)]
struct Node {
  elem: i32,
  next: Link,
}

impl List {
    pub fn new() -> Self {
      List { head: Link::Empty }
    }

    pub fn push(&mut self, elem: i32) {
      let new_node = Box::new(Node {
        elem: elem,
        next: std::mem::replace(&mut self.head, Link::Empty)
      });

      self.head = Link::More(new_node);
    }

    pub fn pop(&mut self) -> Option<i32> {
      match std::mem::replace(&mut self.head, Link::Empty) {
          Link::Empty => None,
          Link::More(node) => {
            self.head = node.next;
            Some(node.elem)
          }
      }
    }
}

impl Drop for List {
  fn drop(&mut self) {
    let mut cur_link = std::mem::replace(&mut self.head, Link::Empty);
    while let Link::More(mut boxed_node) = cur_link {
      cur_link = std::mem::replace(&mut boxed_node.next, Link::Empty);
    }
  }
}

#[cfg(test)]
mod test {
  use super::*;

  #[test]
  fn basics() {
    let mut list = List::new();
    assert_eq!(list.pop(), None);
  }

  #[test]
  fn basc_push_pop() {
    let mut list = List::new();

    list.push(1);
    list.push(2);
    list.push(3);

    assert_eq!(list.pop(), Some(3));
    assert_eq!(list.pop(), Some(2));

    list.push(4);
    assert_eq!(list.pop(), Some(4));
    assert_eq!(list.pop(), Some(1));
    assert_eq!(list.pop(), None);

  }
  
}