(v: Val, s: &Spec, heap: &HeapPool)
| 102 | } |
| 103 | |
| 104 | fn apply(v: Val, s: &Spec, heap: &HeapPool) -> Result<String, &'static str> { |
| 105 | let is_long = v.is_heap() && matches!(heap.get(v), HeapObj::LongInt(_)); |
| 106 | let is_int_like = v.is_int() || v.is_bool() || is_long; |
| 107 | // Dispatch by type char: int types -> int formatter, float types coerce ints up, `s` only strings. |
| 108 | match s.ty { |
| 109 | 0 | b's' => { |
| 110 | if is_int_like || v.is_float() || v.is_none() { |
| 111 | if s.ty == b's' { return Err("'s' format spec requires a string"); } |
| 112 | // Precision on int -> float-fixed; thousands stays in int path to keep LongInt precision. |
| 113 | if s.precision.is_some() && !is_int_like { |
| 114 | return format_float(v, s, b'f', heap); |
| 115 | } |
| 116 | if s.sep != 0 && is_int_like { |
| 117 | let mut s2 = s.clone(); |
| 118 | s2.ty = b'd'; |
| 119 | return format_int(v, &s2, heap); |
| 120 | } |
| 121 | if s.precision.is_some() { |
| 122 | return format_float(v, s, b'f', heap); |
| 123 | } |
| 124 | if v.is_int() { |
| 125 | return Ok(pad_numeric(s, &itoa_str(v.as_int()))); |
| 126 | } |
| 127 | if is_long |
| 128 | && let HeapObj::LongInt(i) = heap.get(v) { |
| 129 | let mut buf = itoa::Buffer::new(); |
| 130 | return Ok(pad_numeric(s, buf.format(*i))); |
| 131 | } |
| 132 | if v.is_float() { |
| 133 | return format_float(v, s, b'f', heap); |
| 134 | } |
| 135 | } |
| 136 | let raw = display_inline(v, heap); |
| 137 | let truncated = match s.precision { |
| 138 | Some(p) => raw.chars().take(p).collect::<String>(), |
| 139 | None => raw, |
| 140 | }; |
| 141 | Ok(pad_string(s, &truncated)) |
| 142 | } |
| 143 | // `n` is locale-aware decimal; paradigm has no locale, so alias to `d`. |
| 144 | b'd' | b'b' | b'o' | b'x' | b'X' | b'n' => { |
| 145 | if s.precision.is_some() { return Err("precision not allowed in integer format spec"); } |
| 146 | let mut s2 = s.clone(); |
| 147 | if s2.ty == b'n' { s2.ty = b'd'; } |
| 148 | format_int(v, &s2, heap) |
| 149 | } |
| 150 | b'f' | b'F' => format_float(v, s, s.ty, heap), |
| 151 | b'e' | b'E' | b'g' | b'G' => format_float(v, s, s.ty, heap), |
| 152 | b'%' => format_percent(v, s, heap), |
| 153 | b'c' => format_char(v, s), |
| 154 | _ => Err("unknown format type"), |
| 155 | } |
| 156 | } |
| 157 | |
| 158 | fn format_percent(v: Val, s: &Spec, heap: &HeapPool) -> Result<String, &'static str> { |
| 159 | let f = require_float(v, heap)? * 100.0; |
no test coverage detected