Practicing Rust based on the Book: 'Learning Rust with Entirely Too Many Linked Lists'
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

fourth.rs 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. use std::rc::Rc;
  2. use std::cell::{Ref, RefMut, RefCell};
  3. pub struct List<T> {
  4. head: Link<T>,
  5. tail: Link<T>,
  6. }
  7. type Link<T> = Option<Rc<RefCell<Node<T>>>>;
  8. struct Node<T> {
  9. elem: T,
  10. next: Link<T>,
  11. prev: Link<T>,
  12. }
  13. impl<T> Node<T> {
  14. fn new(elem: T) -> Rc<RefCell<Self>> {
  15. Rc::new(RefCell::new(Node {
  16. elem,
  17. prev: None,
  18. next: None,
  19. }))
  20. }
  21. }
  22. impl<T> List<T> {
  23. pub fn new() -> Self {
  24. List { head: None, tail: None }
  25. }
  26. pub fn push_front(&mut self, elem: T) {
  27. let new_head = Node::new(elem);
  28. match self.head.take() {
  29. Some(old_head) => {
  30. old_head.borrow_mut().prev = Some(new_head.clone());
  31. new_head.borrow_mut().next = Some(old_head);
  32. self.head = Some(new_head);
  33. }
  34. None => {
  35. self.tail = Some(new_head.clone());
  36. self.head = Some(new_head);
  37. }
  38. }
  39. }
  40. pub fn pop_front(&mut self) -> Option<T> {
  41. self.head.take().map(|old_head| {
  42. match old_head.borrow_mut().next.take() {
  43. Some(new_head) => {
  44. new_head.borrow_mut().prev.take();
  45. self.head = Some(new_head);
  46. }
  47. None => {
  48. self.tail.take();
  49. }
  50. }
  51. Rc::try_unwrap(old_head).ok().unwrap().into_inner().elem
  52. })
  53. }
  54. pub fn peek_front(&self) -> Option<Ref<T>> {
  55. self.head.as_ref().map(|node| {
  56. Ref::map(node.borrow(), |node| &node.elem)
  57. })
  58. }
  59. pub fn push_back(&mut self, elem: T) {
  60. let new_tail = Node::new(elem);
  61. match self.tail.take() {
  62. Some(old_tail) => {
  63. old_tail.borrow_mut().next = Some(new_tail.clone());
  64. new_tail.borrow_mut().prev = Some(old_tail);
  65. self.tail = Some(new_tail);
  66. }
  67. None => {
  68. self.head = Some(new_tail.clone());
  69. self.tail = Some(new_tail);
  70. }
  71. }
  72. }
  73. pub fn pop_back(&mut self) -> Option<T> {
  74. self.tail.take().map(|old_tail| {
  75. match old_tail.borrow_mut().prev.take() {
  76. Some(new_tail) => {
  77. new_tail.borrow_mut().next.take();
  78. self.tail = Some(new_tail);
  79. }
  80. None => {
  81. self.head.take();
  82. }
  83. }
  84. Rc::try_unwrap(old_tail).ok().unwrap().into_inner().elem
  85. })
  86. }
  87. pub fn peek_back(&self) -> Option<Ref<T>> {
  88. self.tail.as_ref().map(|node| {
  89. Ref::map(node.borrow(), |node| &node.elem)
  90. })
  91. }
  92. pub fn peek_back_mut(&mut self) -> Option<RefMut<T>> {
  93. self.tail.as_ref().map(|node| {
  94. RefMut::map(node.borrow_mut(), |node| &mut node.elem)
  95. })
  96. }
  97. pub fn peek_front_mut(&mut self) -> Option<RefMut<T>> {
  98. self.head.as_ref().map(|node| {
  99. RefMut::map(node.borrow_mut(), |node| &mut node.elem)
  100. })
  101. }
  102. }
  103. pub struct IntoIter<T>(List<T>);
  104. impl<T> List<T> {
  105. pub fn into_iter(self) -> IntoIter<T> {
  106. IntoIter(self)
  107. }
  108. }
  109. impl<T> Iterator for IntoIter<T> {
  110. type Item = T;
  111. fn next(&mut self) -> Option<T> {
  112. self.0.pop_front()
  113. }
  114. }
  115. impl<T> DoubleEndedIterator for IntoIter<T> {
  116. fn next_back(&mut self) -> Option<T> {
  117. self.0.pop_back()
  118. }
  119. }
  120. impl<T> Drop for List<T> {
  121. fn drop(&mut self) {
  122. while self.pop_front().is_some() {}
  123. }
  124. }