Day 1 Afternoon Exercises

Designing a Library

(back to exercise)

  1. // Copyright 2022 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // ANCHOR: setup
  15. struct Library {
  16. books: Vec<Book>,
  17. }
  18. struct Book {
  19. title: String,
  20. year: u16,
  21. }
  22. impl Book {
  23. // This is a constructor, used below.
  24. fn new(title: &str, year: u16) -> Book {
  25. Book {
  26. title: String::from(title),
  27. year,
  28. }
  29. }
  30. }
  31. // This makes it possible to print Book values with {}.
  32. impl std::fmt::Display for Book {
  33. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
  34. write!(f, "{} ({})", self.title, self.year)
  35. }
  36. }
  37. // ANCHOR_END: setup
  38. // ANCHOR: Library_new
  39. impl Library {
  40. fn new() -> Library {
  41. // ANCHOR_END: Library_new
  42. Library { books: Vec::new() }
  43. }
  44. // ANCHOR: Library_len
  45. //fn len(self) -> usize {
  46. // unimplemented!()
  47. //}
  48. // ANCHOR_END: Library_len
  49. fn len(&self) -> usize {
  50. self.books.len()
  51. }
  52. // ANCHOR: Library_is_empty
  53. //fn is_empty(self) -> bool {
  54. // unimplemented!()
  55. //}
  56. // ANCHOR_END: Library_is_empty
  57. fn is_empty(&self) -> bool {
  58. self.books.is_empty()
  59. }
  60. // ANCHOR: Library_add_book
  61. //fn add_book(self, book: Book) {
  62. // unimplemented!()
  63. //}
  64. // ANCHOR_END: Library_add_book
  65. fn add_book(&mut self, book: Book) {
  66. self.books.push(book)
  67. }
  68. // ANCHOR: Library_print_books
  69. //fn print_books(self) {
  70. // unimplemented!()
  71. //}
  72. // ANCHOR_END: Library_print_books
  73. fn print_books(&self) {
  74. for book in &self.books {
  75. println!("{}", book);
  76. }
  77. }
  78. // ANCHOR: Library_oldest_book
  79. //fn oldest_book(self) -> Option<&Book> {
  80. // unimplemented!()
  81. //}
  82. // ANCHOR_END: Library_oldest_book
  83. fn oldest_book(&self) -> Option<&Book> {
  84. self.books.iter().min_by_key(|book| book.year)
  85. }
  86. }
  87. // ANCHOR: main
  88. // This shows the desired behavior. Uncomment the code below and
  89. // implement the missing methods. You will need to update the
  90. // method signatures, including the "self" parameter! You may
  91. // also need to update the variable bindings within main.
  92. fn main() {
  93. let library = Library::new();
  94. //println!("Our library is empty: {}", library.is_empty());
  95. //
  96. //library.add_book(Book::new("Lord of the Rings", 1954));
  97. //library.add_book(Book::new("Alice's Adventures in Wonderland", 1865));
  98. //
  99. //library.print_books();
  100. //
  101. //match library.oldest_book() {
  102. // Some(book) => println!("My oldest book is {book}"),
  103. // None => println!("My library is empty!"),
  104. //}
  105. //
  106. //println!("Our library has {} books", library.len());
  107. }
  108. // ANCHOR_END: main
  109. #[test]
  110. fn test_library_len() {
  111. let mut library = Library::new();
  112. assert_eq!(library.len(), 0);
  113. assert!(library.is_empty());
  114. library.add_book(Book::new("Lord of the Rings", 1954));
  115. library.add_book(Book::new("Alice's Adventures in Wonderland", 1865));
  116. assert_eq!(library.len(), 2);
  117. assert!(!library.is_empty());
  118. }
  119. #[test]
  120. fn test_library_is_empty() {
  121. let mut library = Library::new();
  122. assert!(library.is_empty());
  123. library.add_book(Book::new("Lord of the Rings", 1954));
  124. assert!(!library.is_empty());
  125. }
  126. #[test]
  127. fn test_library_print_books() {
  128. let mut library = Library::new();
  129. library.add_book(Book::new("Lord of the Rings", 1954));
  130. library.add_book(Book::new("Alice's Adventures in Wonderland", 1865));
  131. // We could try and capture stdout, but let us just call the
  132. // method to start with.
  133. library.print_books();
  134. }
  135. #[test]
  136. fn test_library_oldest_book() {
  137. let mut library = Library::new();
  138. assert!(library.oldest_book().is_none());
  139. library.add_book(Book::new("Lord of the Rings", 1954));
  140. assert_eq!(
  141. library.oldest_book().map(|b| b.title.as_str()),
  142. Some("Lord of the Rings")
  143. );
  144. library.add_book(Book::new("Alice's Adventures in Wonderland", 1865));
  145. assert_eq!(
  146. library.oldest_book().map(|b| b.title.as_str()),
  147. Some("Alice's Adventures in Wonderland")
  148. );
  149. }