(
&self,
pystr: PyUtf8StrRef,
char_idx: usize,
byte_idx: usize,
scan_once: PyObjectRef,
vm: &VirtualMachine,
)
| 90 | #[pyclass(with(Callable, Constructor))] |
| 91 | impl JsonScanner { |
| 92 | fn parse( |
| 93 | &self, |
| 94 | pystr: PyUtf8StrRef, |
| 95 | char_idx: usize, |
| 96 | byte_idx: usize, |
| 97 | scan_once: PyObjectRef, |
| 98 | vm: &VirtualMachine, |
| 99 | ) -> PyResult<PyIterReturn> { |
| 100 | flame_guard!("JsonScanner::parse"); |
| 101 | let bytes = pystr.as_bytes(); |
| 102 | let wtf8 = pystr.as_wtf8(); |
| 103 | |
| 104 | let first_byte = match bytes.get(byte_idx) { |
| 105 | Some(&b) => b, |
| 106 | None => { |
| 107 | return Ok(PyIterReturn::StopIteration(Some( |
| 108 | vm.ctx.new_int(char_idx).into(), |
| 109 | ))); |
| 110 | } |
| 111 | }; |
| 112 | |
| 113 | match first_byte { |
| 114 | b'"' => { |
| 115 | // Parse string - pass slice starting after the quote |
| 116 | let (wtf8_result, chars_consumed, _bytes_consumed) = |
| 117 | machinery::scanstring(&wtf8[byte_idx + 1..], char_idx + 1, self.strict) |
| 118 | .map_err(|e| py_decode_error(e, pystr.clone().into_wtf8(), vm))?; |
| 119 | let end_char_idx = char_idx + 1 + chars_consumed; |
| 120 | return Ok(PyIterReturn::Return( |
| 121 | vm.new_tuple((wtf8_result, end_char_idx)).into(), |
| 122 | )); |
| 123 | } |
| 124 | b'{' => { |
| 125 | // Parse object in Rust |
| 126 | let mut memo = HashMap::new(); |
| 127 | return self |
| 128 | .parse_object(pystr, char_idx + 1, byte_idx + 1, &scan_once, &mut memo, vm) |
| 129 | .map(|(obj, end_char, _end_byte)| { |
| 130 | PyIterReturn::Return(vm.new_tuple((obj, end_char)).into()) |
| 131 | }); |
| 132 | } |
| 133 | b'[' => { |
| 134 | // Parse array in Rust |
| 135 | let mut memo = HashMap::new(); |
| 136 | return self |
| 137 | .parse_array(pystr, char_idx + 1, byte_idx + 1, &scan_once, &mut memo, vm) |
| 138 | .map(|(obj, end_char, _end_byte)| { |
| 139 | PyIterReturn::Return(vm.new_tuple((obj, end_char)).into()) |
| 140 | }); |
| 141 | } |
| 142 | _ => {} |
| 143 | } |
| 144 | |
| 145 | let s = &pystr.as_str()[byte_idx..]; |
| 146 | |
| 147 | macro_rules! parse_const { |
| 148 | ($s:literal, $val:expr) => { |
| 149 | if s.starts_with($s) { |
no test coverage detected