According to the documentation:
There are three possible ways to specify the desired precision:
An integer .N:
the integer N itself is the precision.
An integer or name followed by dollar sign .N$:
use format argument N (which must be a usize) as the precision.
An asterisk .*:
.* means that this {...} is associated with two format inputs rather than one: the first input holds the usize precision, and the second holds the value to print. Note that in this case, if one uses the format string {<arg>:<spec>.*}, then the <arg> part refers to the value to print, and the precision must come in the input preceding <arg>.
That is, you can use:
fn convert(val: f32, precision: usize) -> String {
format!("{:.prec$}", val, prec = precision)
}
fn main() {
println!("{}", convert(3.14, 0));
println!("{}", convert(3.14, 1));
println!("{}", convert(3.14, 2));
println!("{}", convert(3.14, 3));
}
(Permalink to the playground)