Part 5. Implementing Display (15 points)
The debug representation of a type—the thing you get from the {:?} format
specifier—is extremely handy for developers. Rust makes it trivial to
automatically get this representation for almost every type using
#[derive(Debug)] which is why we add it to all of our types.
The downside is that as a user of a program, it kinda sucks: It shows a bunch of internal details about the types and users don’t care about that; it can be too verbose by including data that’s important for the implementation, but not for the end users; it’s hard to read if you don’t know what you’re looking at; and so on.
In this part, you’re going to remedy this by implementing the
std::fmt::Display trait. Unlike Debug, the compiler cannot
derive the Display trait for you. Fortunately, Rust makes this
pretty easy.
Every trait has a list of required methods that must be implemented by a type
that implements a trait. This is just like implementing an interface in Java.
Some traits have 0 required methods. (These so-called “marker” traits convey
information to the compiler. The Copy trait is one such trait. A type that
implements Copy behaves like the primitive types like i32 in that copies
of the data are made rather than moving the data.) Most traits have 1 or a
small handful of methods that must be implemented. Traits can have additional
methods that have default implementations (much like abstract classes in Java).
The Display trait has a single method to implement: fmt(). Read
the documentation for Display and pay particular attention to the
example showing how to implement Display.
The write!() macro and its companion writeln!() work very similarly to the
print!() and println!() macros. There are two differences between
write!()/writeln!() and print!()/println!().
- The
printmacros write tostdoutwhereas thewritemacros write to their first argument, in this case it’s the mutable reference to aFormatterobject; and - The
printmacros will panic (a safe crash) if writing tostdoutfails whereas thewritemacros return aResult.
The upshot of 2 is that if you want to make multiple calls to writeln!() in
the fmt() method, you can use the ? operator as usual.
writeln!(f, "First line")?;
writeln!(f, "Second line")?;
Ok(())
Your task
Implement Display for Entry. It should behave as follows:
- If the entry has an author (i.e., it’s not
None), then the author line should be printed (see examples below) otherwise the author line should be omitted; - Print the title line;
- Print the URL line; and
- If there are resources, print the list of resources.
Change your run() function to print out the Display representation for
each matching entry.
fn run() -> Result<()> {
let index = Index::new()?;
println!("There are {} entries in the index", index.len());
let results = index.title_search("the inferno");
for entry in results {
println!("{entry}");
}
Ok(())
}
If everything has been implemented correctly, the three entries should appear like this.
Author: Barbusse, Henri; O'Brien, Edward J. (Edward Joseph)
Title: The Inferno
URL: https://www.gutenberg.org/ebooks/12414
Resources
- text: https://www.gutenberg.org/ebooks/12414.html.images
- epub: https://www.gutenberg.org/ebooks/12414.epub3.images
- text: https://www.gutenberg.org/ebooks/12414.html.noimages
- epub: https://www.gutenberg.org/ebooks/12414.epub.images
- epub: https://www.gutenberg.org/ebooks/12414.epub.noimages
- text: https://www.gutenberg.org/ebooks/12414.txt.utf-8
- text: https://www.gutenberg.org/files/12414/12414-8.txt
- text: https://www.gutenberg.org/files/12414/12414-8.zip
- text: https://www.gutenberg.org/files/12414/12414.txt
- text: https://www.gutenberg.org/files/12414/12414.zip
Author: Dante Alighieri; Sibbald, James Romanes
Title: The Divine Comedy of Dante Alighieri: The Inferno
URL: https://www.gutenberg.org/ebooks/41537
Resources
- text: https://www.gutenberg.org/ebooks/41537.html.images
- text: https://www.gutenberg.org/files/41537/41537-h/41537-h.htm
- epub: https://www.gutenberg.org/ebooks/41537.epub3.images
- epub: https://www.gutenberg.org/ebooks/41537.epub.images
- epub: https://www.gutenberg.org/ebooks/41537.epub.noimages
- text: https://www.gutenberg.org/ebooks/41537.txt.utf-8
- text: https://www.gutenberg.org/files/41537/41537-0.txt
Author: Strindberg, August; Field, Claud
Title: The Inferno
URL: https://www.gutenberg.org/ebooks/44108
Resources
- text: https://www.gutenberg.org/ebooks/44108.html.images
- text: https://www.gutenberg.org/files/44108/44108-h/44108-h.htm
- text: https://www.gutenberg.org/files/44108/44108-h.zip
- epub: https://www.gutenberg.org/ebooks/44108.epub3.images
- epub: https://www.gutenberg.org/ebooks/44108.epub.images
- epub: https://www.gutenberg.org/ebooks/44108.epub.noimages
- text: https://www.gutenberg.org/files/44108/44108-0.txt
- text: https://www.gutenberg.org/files/44108/44108-0.zip