diff --git a/src/python.rs b/src/python.rs index ba338c6b..c748dd34 100644 --- a/src/python.rs +++ b/src/python.rs @@ -6,82 +6,93 @@ use crate::string_decoder::Tape; use crate::{FilePosition, JsonError, NumberAny, NumberDecoder, NumberInt, Parser, Peak, StringDecoder}; pub fn python_parse(py: Python, data: &[u8]) -> PyResult { - let mut parser = Parser::new(data); + let mut python_parser = PythonParser { + parser: Parser::new(data), + tape: Tape::default(), + data, + }; let mje = |e: JsonError| map_json_error(data, e); - let mut tape = Tape::default(); - let peak = parser.peak().map_err(mje)?; - let v = py_take_value(py, peak, &mut parser, &mut tape, data)?; - parser.finish().map_err(mje)?; + let peak = python_parser.parser.peak().map_err(mje)?; + let v = python_parser.py_take_value(py, peak)?; + python_parser.parser.finish().map_err(mje)?; Ok(v) } -pub(crate) fn py_take_value( - py: Python, - peak: Peak, - parser: &mut Parser, - tape: &mut Tape, - data: &[u8], -) -> PyResult { - let mje = |e: JsonError| map_json_error(data, e); - match peak { - Peak::True => { - parser.consume_true().map_err(mje)?; - Ok(true.to_object(py)) - } - Peak::False => { - parser.consume_false().map_err(mje)?; - Ok(false.to_object(py)) - } - Peak::Null => { - parser.consume_null().map_err(mje)?; - Ok(py.None()) - } - Peak::String => { - let s = parser.consume_string::(tape).map_err(mje)?; - Ok(PyString::new(py, s).to_object(py)) - } - Peak::Num(first) => { - let n = parser.consume_number::>(first).map_err(mje)?; - match n { - NumberAny::Int(NumberInt::Int(int)) => Ok(int.to_object(py)), - NumberAny::Int(NumberInt::BigInt(big_int)) => Ok(big_int.to_object(py)), - NumberAny::Int(NumberInt::Zero) => Ok(0.to_object(py)), - NumberAny::Float(float) => Ok(float.to_object(py)), +struct PythonParser<'j> { + parser: Parser<'j>, + tape: Tape, + data: &'j [u8], +} + +impl<'j> PythonParser<'j> { + fn py_take_value(&mut self, py: Python, peak: Peak) -> PyResult { + let mje = |e: JsonError| map_json_error(self.data, e); + match peak { + Peak::True => { + self.parser.consume_true().map_err(mje)?; + Ok(true.to_object(py)) } - } - Peak::Array => { - // TODO we should create the list with the correct size and insert directly into it - let mut vec = Vec::new(); - if let Some(peak_first) = parser.array_first().map_err(mje)? { - let v = py_take_value(py, peak_first, parser, tape, data)?; - vec.push(v); - while parser.array_step().map_err(mje)? { - let peak = parser.peak().map_err(mje)?; - let v = py_take_value(py, peak, parser, tape, data)?; - vec.push(v); + Peak::False => { + self.parser.consume_false().map_err(mje)?; + Ok(false.to_object(py)) + } + Peak::Null => { + self.parser.consume_null().map_err(mje)?; + Ok(py.None()) + } + Peak::String => { + let s = self + .parser + .consume_string::(&mut self.tape) + .map_err(mje)?; + Ok(PyString::new(py, s).to_object(py)) + } + Peak::Num(first) => { + let n = self + .parser + .consume_number::>(first) + .map_err(mje)?; + match n { + NumberAny::Int(NumberInt::Int(int)) => Ok(int.to_object(py)), + NumberAny::Int(NumberInt::BigInt(big_int)) => Ok(big_int.to_object(py)), + NumberAny::Int(NumberInt::Zero) => Ok(0.to_object(py)), + NumberAny::Float(float) => Ok(float.to_object(py)), } } - let list = PyList::new(py, vec); - Ok(list.to_object(py)) - } - Peak::Object => { - let dict = PyDict::new(py); - if let Some(first_key) = parser.object_first::(tape).map_err(mje)? { - let first_key = PyString::new(py, first_key); - let peak = parser.peak().map_err(mje)?; - let first_value = py_take_value(py, peak, parser, tape, data)?; - dict.set_item(first_key, first_value)?; - while let Some(key) = parser.object_step::(tape).map_err(mje)? { - let key = PyString::new(py, key); - let peak = parser.peak().map_err(mje)?; - let value = py_take_value(py, peak, parser, tape, data)?; - dict.set_item(key, value)?; + Peak::Array => { + // TODO we should create the list with the correct size and insert directly into it + let mut vec = Vec::new(); + if let Some(peak_first) = self.parser.array_first().map_err(mje)? { + let v = self.py_take_value(py, peak_first)?; + vec.push(v); + while self.parser.array_step().map_err(mje)? { + let peak = self.parser.peak().map_err(mje)?; + let v = self.py_take_value(py, peak)?; + vec.push(v); + } } + let list = PyList::new(py, vec); + Ok(list.to_object(py)) } + Peak::Object => { + let dict = PyDict::new(py); + if let Some(first_key) = self.parser.object_first::(&mut self.tape).map_err(mje)? { + let first_key = PyString::new(py, first_key); + let peak = self.parser.peak().map_err(mje)?; + let first_value = self.py_take_value(py, peak)?; + dict.set_item(first_key, first_value)?; + while let Some(key) = self.parser.object_step::(&mut self.tape).map_err(mje)? { + let key = PyString::new(py, key); + let peak = self.parser.peak().map_err(mje)?; + let value = self.py_take_value(py, peak)?; + dict.set_item(key, value)?; + } + } - Ok(dict.to_object(py)) + Ok(dict.to_object(py)) + } } } }