(vm: &VirtualMachine, js_val: JsValue)
| 179 | } |
| 180 | |
| 181 | pub fn js_to_py(vm: &VirtualMachine, js_val: JsValue) -> PyObjectRef { |
| 182 | if js_val.is_object() { |
| 183 | if let Some(promise) = js_val.dyn_ref::<Promise>() { |
| 184 | // the browser module might not be injected |
| 185 | if vm.try_class("browser", "Promise").is_ok() { |
| 186 | return js_module::PyPromise::new(promise.clone()) |
| 187 | .into_ref(&vm.ctx) |
| 188 | .into(); |
| 189 | } |
| 190 | } |
| 191 | if Array::is_array(&js_val) { |
| 192 | let js_arr: Array = js_val.into(); |
| 193 | let elems = js_arr |
| 194 | .values() |
| 195 | .into_iter() |
| 196 | .map(|val| js_to_py(vm, val.expect("Iteration over array failed"))) |
| 197 | .collect(); |
| 198 | vm.ctx.new_list(elems).into() |
| 199 | } else if ArrayBuffer::is_view(&js_val) || js_val.is_instance_of::<ArrayBuffer>() { |
| 200 | // unchecked_ref because if it's not an ArrayBuffer it could either be a TypedArray |
| 201 | // or a DataView, but they all have a `buffer` property |
| 202 | let u8_array = js_sys::Uint8Array::new( |
| 203 | &js_val |
| 204 | .dyn_ref::<ArrayBuffer>() |
| 205 | .cloned() |
| 206 | .unwrap_or_else(|| js_val.unchecked_ref::<Uint8Array>().buffer()), |
| 207 | ); |
| 208 | let mut vec = vec![0; u8_array.length() as usize]; |
| 209 | u8_array.copy_to(&mut vec); |
| 210 | vm.ctx.new_bytes(vec).into() |
| 211 | } else { |
| 212 | let dict = vm.ctx.new_dict(); |
| 213 | for pair in object_entries(&Object::from(js_val)) { |
| 214 | let (key, val) = pair.expect("iteration over object to not fail"); |
| 215 | let py_val = js_to_py(vm, val); |
| 216 | dict.set_item( |
| 217 | String::from(js_sys::JsString::from(key)).as_str(), |
| 218 | py_val, |
| 219 | vm, |
| 220 | ) |
| 221 | .unwrap(); |
| 222 | } |
| 223 | dict.into() |
| 224 | } |
| 225 | } else if js_val.is_function() { |
| 226 | let func = js_sys::Function::from(js_val); |
| 227 | vm.new_function( |
| 228 | vm.ctx.intern_str(String::from(func.name())).as_str(), |
| 229 | move |args: FuncArgs, vm: &VirtualMachine| -> PyResult { |
| 230 | let this = Object::new(); |
| 231 | for (k, v) in args.kwargs { |
| 232 | Reflect::set(&this, &k.into(), &py_to_js(vm, v)) |
| 233 | .expect("property to be settable"); |
| 234 | } |
| 235 | let js_args = args |
| 236 | .args |
| 237 | .into_iter() |
| 238 | .map(|v| py_to_js(vm, v)) |
no test coverage detected