use crate::interpreter::RuntimeValue;
pub fn apply_format_spec(val: &RuntimeValue, spec: &str) -> String {
if spec == "$" {
if let RuntimeValue::BigInt(b) = val {
return format!("${}.00", b);
}
let f = match val {
RuntimeValue::Float(f) => *f,
RuntimeValue::Int(n) => *n as f64,
_ => return format!("${}", val.to_display_string()),
};
return format!("${:.2}", f);
}
if spec.starts_with('.') {
if let Ok(precision) = spec[1..].parse::<usize>() {
match val {
RuntimeValue::Float(f) => return format!("{:.prec$}", f, prec = precision),
RuntimeValue::Int(n) => return format!("{:.prec$}", *n as f64, prec = precision),
RuntimeValue::BigInt(b) => return format!("{:.prec$}", b.to_f64(), prec = precision),
_ => return val.to_display_string(),
}
}
}
if spec.len() >= 2 {
let first = spec.as_bytes()[0];
if first == b'>' || first == b'<' || first == b'^' {
if let Ok(width) = spec[1..].parse::<usize>() {
let s = val.to_display_string();
return match first {
b'>' => format!("{:>w$}", s, w = width),
b'<' => format!("{:<w$}", s, w = width),
b'^' => format!("{:^w$}", s, w = width),
_ => unreachable!(),
};
}
}
}
if let Ok(width) = spec.parse::<usize>() {
let s = val.to_display_string();
return format!("{:>w$}", s, w = width);
}
val.to_display_string()
}