Reputation: 114
I want to apply format arguments (for example to limit the amount of digits) to the members of my struct. My current implementation looks roughly like this:
use std::fmt;
#[derive(Debug)]
pub struct Vec2 { x: f32, y: f32 }
impl fmt::Display for Vec2 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[{}, {}]", self.x, self.y)
}
}
If I use the automatically derived debug printing using e.g. {:.2?}
, the arguments are applied and only 2 places after the decimal are printed. This doesn't seem to work with my Display
implementation though using {:.2}
. I tried to look at the Debug implementation using cargo expand
but there are many functions specifically for Debug
.
Upvotes: 1
Views: 709
Reputation: 70990
The easiest way will be to forward the formatting:
impl fmt::Display for Vec2 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("[")?;
fmt::Display::fmt(&self.x, f)?;
f.write_str(", ")?;
fmt::Display::fmt(&self.y, f)?;
f.write_str("]")
}
}
Note that if you want to have all formatting specifiers, you have to implement additional traits. For floats, it's only std::fmt::LowerExp
and std::fmt::UpperExp
. You can make a little helper function to not duplicate code:
impl Vec2 {
fn fmt(
&self,
f: &mut fmt::Formatter<'_>,
fmt_fn: fn(&f32, f: &mut fmt::Formatter<'_>) -> fmt::Result,
) -> fmt::Result {
f.write_str("[")?;
fmt_fn(&self.x, f)?;
f.write_str(", ")?;
fmt_fn(&self.y, f)?;
f.write_str("]")
}
}
impl fmt::Display for Vec2 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.fmt(f, fmt::Display::fmt)
}
}
impl fmt::LowerExp for Vec2 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.fmt(f, fmt::LowerExp::fmt)
}
}
impl fmt::UpperExp for Vec2 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.fmt(f, fmt::UpperExp::fmt)
}
}
Upvotes: 1