Reputation: 209
Given this Rust program, which prints 1.23456
:
use std::fmt;
struct Foo(f64);
impl fmt::Display for Foo {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "{}", self.0)
}
}
fn main() {
println!("{:.2}", Foo(1.23456));
}
Which the simplest change to the body of the function fmt
, to get printed 1.23
?
In general, is there a simple way to use inside the function fmt
the same formatting options set by the code which prints the object? I know the formatter object has several methods which access formatting options, but is there a simple method to obtain always the same result which is obtained by calling println!("{:.2}", Foo(1.23456).0);
?
Upvotes: 2
Views: 124
Reputation: 27550
Your usecase is actually covered in the documentation of Formatter
, the number after the .
is called the precision and you can pass it like this:
impl fmt::Display for Foo { fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { if let Some(precision) = formatter.precision() { // If we received a precision, we use it. write!(formatter, "Foo({1:.*})", precision, self.0) } else { // Otherwise we default to 2. write!(formatter, "Foo({:.2})", self.0) } } }
Of course you might want to default to a different precision, or not specify one in the else
branch.
For reference the functions you can use to access different parts of the specified format are:
align
alternate
fill
flags
(deprecated)precision
sign_aware_zero_pad
sign_minus
sign_plus
width
Upvotes: 1
Reputation: 2197
To pass all formatting options to .0
, you can just call .fmt
on it:
use std::fmt;
struct Foo(f64);
impl fmt::Display for Foo {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(formatter)
}
}
fn main() {
println!("{:.2}", Foo(1.23456));
}
(See playground)
Upvotes: 6