In this lesson, you will learn how to take control of how your custom types appear in logs and terminal output by manually implementing the std::fmt::Debug and std::fmt::Display traits.
Why Customize Representation?
By default, Rust allows you to use the #[derive(Debug)] attribute to print structs and enums. However, once your data structures become complex, the default "struct-style" output might be too verbose or hide the information most relevant to your debugging process. Similarly, Display allows you to define a user-facing, clean version of your data that isn't intended for developers, but for end-users.
Implementing Debug and Display
The Debug trait is intended for developers ({:?}), while Display is intended for clean, readable output ({}).
Here is how you manually implement them:
use std::fmt;
struct User {
id: u32,
username: String,
}
// Custom Debug: Optimized for developer inspection
impl fmt::Debug for User {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "User(id: {}, name: '{}')", self.id, self.username)
}
}
// Custom Display: Optimized for end-user readability
impl fmt::Display for User {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} (ID: {})", self.username, self.id)
}
}
The fmt Method
Both traits require you to implement the fmt method. The f: &mut fmt::Formatter acts as a buffer. The write! macro is your primary tool here; it functions exactly like println!, but instead of writing to the standard output, it writes directly into the formatter provided by the trait.
Debug({:?}): Use this to show internal state, even if it is technical or messy. It is your diagnostic tool.Display({}): Use this to present data elegantly. If you don't implementDisplay, your type cannot be used with the{}placeholder in format strings.
By controlling these implementations, you turn opaque data structures into clear, observable signals during runtime, making your code significantly easier to maintain and troubleshoot.
Key Takeaway: Implement Debug for developer diagnostics and Display for user-facing output to ensure your data is always presented exactly how you need it.