I want to implement the fmt::Display
for a nested struct commonly used in my code.
// The root structure
pub struct WhisperFile<'a> {
pub path: &'a str,
pub handle: RefCell<File>,
pub header: Header
}
pub struct Header{
pub metadata: metadata::Metadata,
pub archive_infos: Vec<archive_info::ArchiveInfo>
}
pub struct Metadata {
// SNIP
}
pub struct ArchiveInfo {
// SNIP
}
As you can see, this is a non-trivial tree of data. The archive_infos
property on Header
can be quite long when presented as one line.
I would like to emit something along the lines of
WhisperFile ({PATH})
Metadata
...
ArchiveInfo (0)
...
ArchiveInfo (N)
...
But when I try to display Vec<ArchiveInfo>
I get that Display is not implemented. I can implement fmt::Display
for ArchiveInfo
but that's not enough since fmt::Display
is not implemented for the parent container Vec
. If I implement fmt::Display for collections::vec::Vec<ArchiveInfo>
I get the impl does not reference any types defined in this crate; only traits defined in the current crate can be implemented for arbitrary types
.
I have tried iterating over the vec and calling write!()
but I couldn't figure out what the control flow should look like. I think write!()
needs to be return value of the function but that breaks down with multiple calls.
How can I pretty print a Vec of my structures?
Trait std::fmt::DisplayFormat trait for an empty format, {} . Display is similar to Debug , but Display is for user-facing output, and so cannot be derived. For more information on formatters, see the module-level documentation.
When interpolating values into a string in a println! call, you use the {} symbols in a format string followed by the variables as arguments. What this is using to insert a user-facing output into the string is the fmt::Display trait.
As this error states, you cannot implement a trait for a type you don't own:
the impl does not reference any types defined in this crate; only traits defined in the current crate can be implemented for arbitrary types
However, you can implement Display
for your wrapper type. The piece you are missing is to use the try!
macro or the try operator ?
:
use std::fmt;
struct Foo(Vec<u8>);
impl fmt::Display for Foo {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Values:\n")?;
for v in &self.0 {
write!(f, "\t{}", v)?;
}
Ok(())
}
}
fn main() {
let f = Foo(vec![42]);
println!("{}", f);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With