(tk: &mut Tokenizer, ctx: &LoadCtx)
| 121 | } |
| 122 | |
| 123 | fn parse_object_pairs(tk: &mut Tokenizer, ctx: &LoadCtx) -> Result<Handle> { |
| 124 | let mut pairs: Vec<(Handle, Handle)> = Vec::new(); |
| 125 | let first = tk.next_token().map_err(to_pdk_err)?; |
| 126 | if !matches!(first, Token::RBrace) { |
| 127 | let mut current = first; |
| 128 | loop { |
| 129 | let key_str = match current { |
| 130 | Token::Str(s) => s, |
| 131 | _ => return Err(value_err(tk.pos(), "object key must be a string")), |
| 132 | }; |
| 133 | let key = encode(Value::Bytes(key_str.into_bytes()))?; |
| 134 | match tk.next_token().map_err(to_pdk_err)? { |
| 135 | Token::Colon => {} |
| 136 | _ => return Err(value_err(tk.pos(), "expected ':' after object key")), |
| 137 | } |
| 138 | let value = parse_value(tk, ctx)?; |
| 139 | pairs.push((key, value)); |
| 140 | match tk.next_token().map_err(to_pdk_err)? { |
| 141 | Token::Comma => current = tk.next_token().map_err(to_pdk_err)?, |
| 142 | Token::RBrace => break, |
| 143 | _ => return Err(value_err(tk.pos(), "expected ',' or '}' in object")), |
| 144 | } |
| 145 | } |
| 146 | } |
| 147 | // Materialise as `list[list[key, val]]`; CPython hands `list[tuple]` but wasm-pdk has no `new_tuple` (the hook can `tuple(p) for p in pairs` if it needs them). |
| 148 | let list = Handle::new_list()?; |
| 149 | for (k, v) in pairs { |
| 150 | let pair = Handle::new_list()?; |
| 151 | pair.call("append", &[k.raw()])?; |
| 152 | pair.call("append", &[v.raw()])?; |
| 153 | list.call("append", &[pair.raw()])?; |
| 154 | } |
| 155 | let hook = ctx.object_pairs_hook.as_ref().unwrap(); |
| 156 | hook.call("__call__", &[list.raw()]) |
| 157 | } |
| 158 | |
| 159 | fn apply_object_hook(dict: Handle, ctx: &LoadCtx) -> Result<Handle> { |
| 160 | if let Some(hook) = &ctx.object_hook { |
no test coverage detected