Pattern matching in Rust is a powerful feature that allows you to destructure and inspect complex data types in a concise and readable manner. By using match statements, you can handle different variants of enums, tuples, and other data structures, applying specific logic based on the shape and content of the data.
This challenge will help you practice advanced pattern matching techniques in a real-world scenario.
Your Task
You need to implement a method check_validity(&self) for the BookItem enum that returns a bool indicating whether the item is valid based on the following rules:
-
Book:
- The number of pages must be greater than 0.
- If there is a discount:
- Must be non-negative (≥ 0)
- Must not exceed 50% (≤ 50)
-
EBook:
- The title (a
String) must be non-empty. - The second field in the tuple must be greater than 0.
- The title (a
-
Collection:
- Must not be empty
- ALL items in the collection must be valid
- This means a collection containing even one invalid item is considered invalid
-
OutOfPrint:
- This variant is always considered invalid.
Requirements
- Implement
check_validity(&self)using match guards to reflect these rules. - Return a boolean (
trueorfalse) based on the type ofBookItem. - Ensure that the function does not panic for any valid input.
Hints
<details> <summary>Click here to reveal hints</summary>- Use
ifguards to combine multiple conditions:if *pages > 0 && *d >= 0 - Pattern match on
Option<i32>usingSome(d)andNone - For Collections:
- Check
!items.is_empty()first - Use
iter().all(|item| item.check_validity())to ensure all items are valid
- Check
- Remember to dereference numbers when using them in guards:
*pages,*second - The catch-all
_ => falsearm handles any remaining invalid cases
← PreviousNext →
#[derive(Debug)]pub enum BookItem {Book { pages: i32, discount: Option<i32> },EBook(String, (i32, i32)),Collection(Vec<BookItem>),OutOfPrint,}impl BookItem {// TODO: Finish the implementation}// Example usagepub fn main() {let book_a = BookItem::Book {pages: 42,discount: Some(100),};let ebook_b = BookItem::EBook("hello".to_string(), (1, 2));let collection_c = BookItem::Collection(vec![book_a.clone(), BookItem::OutOfPrint]);assert!(!book_a.check_validity(),"Book with discount > 50 should be invalid");assert!(ebook_b.check_validity(),"EBook with valid title and tuple should be valid");assert!(!collection_c.check_validity(),"Collection containing invalid items should be invalid");assert!(!BookItem::OutOfPrint.check_validity(),"OutOfPrint should always be invalid");}