Part 4. Modeling resources (10 points)
In this part, you’re going to create a new type, an enumeration (enum
)
rather than a structure type (struct
), in order to represent (or model) a
resource associated with the entries in the Project Gutenberg index.
Briefly, an enum
lets us model the situation where a value is one of a
finite set of choices. For example, the Option<T>
type is either None
or
it’s a Some(x)
(for some value x
of type T
). Review Chapter
6 of the Rust book
as needed for details on enum
s.
In this case, there are three different types of resources: epub (an ebook format), text, and audio.
Let’s return to the example index entry we saw before:
Roosevelt, Wyn; Schneider, S. The Frontier Boys in the Sierras; Or, The Lost Mine https://www.gutenberg.org/ebooks/32253 text https://www.gutenberg.org/ebooks/32253.html.images text https://www.gutenberg.org/files/32253/32253-h/32253-h.htm text https://www.gutenberg.org/files/32253/32253-h.zip epub https://www.gutenberg.org/ebooks/32253.epub3.images epub https://www.gutenberg.org/ebooks/32253.epub.images epub https://www.gutenberg.org/ebooks/32253.epub.noimages text https://www.gutenberg.org/ebooks/32253.txt.utf-8 text https://www.gutenberg.org/files/32253/32253-8.txt text https://www.gutenberg.org/files/32253/32253-8.zip text https://www.gutenberg.org/files/32253/32253.txt text https://www.gutenberg.org/files/32253/32253.zip
Each of the tab-separated fields after the author, title, and URL fields
consists of the word epub
, text
, or audio
followed by a space and then a
URL of the resource in question.
Your task
Define a new enum Resource
which has variants corresponding to the epub,
text, and audio resources. Each variant should hold its corresponding URL. For
inspiration, look at the definition of enum IpAddr
in the
book.
You should make sure you derive Debug
as normal so that you can print the
debug representation using the {:?}
format specifier.
let x = Resource::Audio("https://example.com");
println!("{x:?}"); // Prints debug representation of `x`
Next, modify your Entry
structure to hold 0 or more Resource
s and update
Index::new()
to correctly fill in the resources from the resource fields
pgindex.txt
.
You can split each resource field on a space and then match
on the first part.
fn main() -> Result<(), Box<dyn std::error::Error>> { let parts = vec!["audio", "https://example.com"]; match parts[0] { "epub" => todo!(), "text" => todo!(), "audio" => todo!(), _ => return Err(format!("Unknown format: {}", parts[0]).into()), } Ok(()) }
How cool is that?
At this point, the run()
function from the previous part should work
(assuming you derived Debug
as suggested) and its output should include all
of the resources associated with each of the three entries matching the query.