1#[macro_export]
2macro_rules! fmt_with_width {
3 ($f:expr, $s:expr) => {{
4 if $f.fill() != ' ' && $f.fill() != '\0' {
5 unimplemented!("Specifying fill is not supported. Rust is letting us down, impossible to implement, call `to_string()` and use its implementation.");
6 }
7 if let Some(w) = $f.width() {
8 match $f.align() {
9 Some(std::fmt::Alignment::Left) => write!($f, "{:<width$}", $s, width = w),
10 Some(std::fmt::Alignment::Right) => write!($f, "{:>width$}", $s, width = w),
11 Some(std::fmt::Alignment::Center) => write!($f, "{:^width$}", $s, width = w),
12 _ => write!($f, "{:width$}", $s, width = w),
13 }
14 } else {
15 write!($f, "{}", $s)
16 }
17 }};
18}
19
20pub fn format_significant_digits(n: f64, sig_digits: usize) -> String {
26 if n == 0.0 {
27 return "0".to_string();
28 }
29
30 let full = format!("{:.12}", n.abs());
31 if !full.contains('.') {
32 return format!("{n:.1}");
33 }
34
35 let first_sig = full.chars().position(|c| c != '0' && c != '.').unwrap_or(0);
36
37 let mut sig_count = 0;
38 let mut last_pos = full.len();
39 for (i, c) in full.chars().enumerate().skip(first_sig) {
40 if c != '.' {
41 sig_count += 1;
42 if sig_count == sig_digits {
43 last_pos = i + 1;
44 break;
45 }
46 }
47 }
48
49 let precision = full[..last_pos].split('.').nth(1).unwrap_or("").len();
50 format!("{:.*}", precision, n)
51}