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
print
macros write tostdout
whereas thewrite
macros write to their first argument, in this case it’s the mutable reference to aFormatter
object; and - The
print
macros will panic (a safe crash) if writing tostdout
fails whereas thewrite
macros 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