Parse a JSON array starting after the opening '['. Returns (parsed_array, end_char_index, end_byte_index).
(
&self,
pystr: PyUtf8StrRef,
start_char_idx: usize,
start_byte_idx: usize,
scan_once: &PyObjectRef,
memo: &mut HashMap<String,
| 388 | /// Parse a JSON array starting after the opening '['. |
| 389 | /// Returns (parsed_array, end_char_index, end_byte_index). |
| 390 | fn parse_array( |
| 391 | &self, |
| 392 | pystr: PyUtf8StrRef, |
| 393 | start_char_idx: usize, |
| 394 | start_byte_idx: usize, |
| 395 | scan_once: &PyObjectRef, |
| 396 | memo: &mut HashMap<String, PyStrRef>, |
| 397 | vm: &VirtualMachine, |
| 398 | ) -> PyResult<(PyObjectRef, usize, usize)> { |
| 399 | flame_guard!("JsonScanner::parse_array"); |
| 400 | |
| 401 | let bytes = pystr.as_bytes(); |
| 402 | let mut char_idx = start_char_idx; |
| 403 | let mut byte_idx = start_byte_idx; |
| 404 | |
| 405 | // Skip initial whitespace |
| 406 | let ws = skip_whitespace(&bytes[byte_idx..]); |
| 407 | char_idx += ws; |
| 408 | byte_idx += ws; |
| 409 | |
| 410 | // Check for empty array |
| 411 | if bytes.get(byte_idx) == Some(&b']') { |
| 412 | return Ok((vm.ctx.new_list(vec![]).into(), char_idx + 1, byte_idx + 1)); |
| 413 | } |
| 414 | |
| 415 | let mut values: Vec<PyObjectRef> = Vec::new(); |
| 416 | |
| 417 | loop { |
| 418 | // Parse value |
| 419 | let (value, value_char_end, value_byte_end) = |
| 420 | self.call_scan_once(scan_once, pystr.clone(), char_idx, byte_idx, memo, vm)?; |
| 421 | |
| 422 | values.push(value); |
| 423 | char_idx = value_char_end; |
| 424 | byte_idx = value_byte_end; |
| 425 | |
| 426 | // Skip whitespace after value |
| 427 | let ws = skip_whitespace(&bytes[byte_idx..]); |
| 428 | char_idx += ws; |
| 429 | byte_idx += ws; |
| 430 | |
| 431 | match bytes.get(byte_idx) { |
| 432 | Some(b']') => { |
| 433 | char_idx += 1; |
| 434 | byte_idx += 1; |
| 435 | break; |
| 436 | } |
| 437 | Some(b',') => { |
| 438 | let comma_char_idx = char_idx; |
| 439 | char_idx += 1; |
| 440 | byte_idx += 1; |
| 441 | |
| 442 | // Skip whitespace after comma |
| 443 | let ws = skip_whitespace(&bytes[byte_idx..]); |
| 444 | char_idx += ws; |
| 445 | byte_idx += ws; |
| 446 | |
| 447 | // Check for trailing comma |
no test coverage detected