(
vm: &VirtualMachine,
spec: &CFormatSpec,
obj: PyObjectRef,
idx: usize,
)
| 124 | } |
| 125 | |
| 126 | fn spec_format_string( |
| 127 | vm: &VirtualMachine, |
| 128 | spec: &CFormatSpec, |
| 129 | obj: PyObjectRef, |
| 130 | idx: usize, |
| 131 | ) -> PyResult<Wtf8Buf> { |
| 132 | match &spec.format_type { |
| 133 | CFormatType::String(conversion) => { |
| 134 | let result = match conversion { |
| 135 | CFormatConversion::Ascii => builtins::ascii(obj, vm)?.as_wtf8().to_owned(), |
| 136 | CFormatConversion::Str => obj.str(vm)?.as_wtf8().to_owned(), |
| 137 | CFormatConversion::Repr => obj.repr(vm)?.as_wtf8().to_owned(), |
| 138 | CFormatConversion::Bytes => { |
| 139 | // idx is the position of the %, we want the position of the b |
| 140 | return Err(vm.new_value_error(format!( |
| 141 | "unsupported format character 'b' (0x62) at index {}", |
| 142 | idx + 1 |
| 143 | ))); |
| 144 | } |
| 145 | }; |
| 146 | Ok(spec.format_string(result)) |
| 147 | } |
| 148 | CFormatType::Number(number_type) => match number_type { |
| 149 | CNumberType::DecimalD | CNumberType::DecimalI | CNumberType::DecimalU => { |
| 150 | match_class!(match &obj { |
| 151 | ref i @ PyInt => { |
| 152 | Ok(spec.format_number(i.as_bigint()).into()) |
| 153 | } |
| 154 | ref f @ PyFloat => { |
| 155 | Ok(spec |
| 156 | .format_number(&try_f64_to_bigint(f.to_f64(), vm)?) |
| 157 | .into()) |
| 158 | } |
| 159 | obj => { |
| 160 | if let Some(method) = vm.get_method(obj.clone(), identifier!(vm, __int__)) { |
| 161 | let result = method?.call((), vm)?; |
| 162 | if let Some(i) = result.downcast_ref::<PyInt>() { |
| 163 | return Ok(spec.format_number(i.as_bigint()).into()); |
| 164 | } |
| 165 | } |
| 166 | Err(vm.new_type_error(format!( |
| 167 | "%{} format: a number is required, not {}", |
| 168 | spec.format_type.to_char(), |
| 169 | obj.class().name() |
| 170 | ))) |
| 171 | } |
| 172 | }) |
| 173 | } |
| 174 | _ => { |
| 175 | if let Some(i) = obj.downcast_ref::<PyInt>() { |
| 176 | Ok(spec.format_number(i.as_bigint()).into()) |
| 177 | } else { |
| 178 | Err(vm.new_type_error(format!( |
| 179 | "%{} format: an integer is required, not {}", |
| 180 | spec.format_type.to_char(), |
| 181 | obj.class().name() |
| 182 | ))) |
| 183 | } |
no test coverage detected