@@ -6,11 +6,8 @@ use super::ffi::{
66 yyjson_read_opts, yyjson_val,
77} ;
88use crate :: deserialize:: DeserializeError ;
9- use crate :: deserialize:: pyobject:: {
10- get_unicode_key, parse_f64, parse_false, parse_i64, parse_none, parse_true, parse_u64,
11- } ;
12- use crate :: ffi:: PyStrRef ;
13- use crate :: util:: usize_to_isize;
9+ use crate :: deserialize:: pyobject:: get_unicode_key;
10+ use crate :: ffi:: { PyBoolRef , PyDictRef , PyFloatRef , PyIntRef , PyListRef , PyNoneRef , PyStrRef } ;
1411use core:: ffi:: c_char;
1512use core:: ptr:: { NonNull , null, null_mut} ;
1613use std:: borrow:: Cow ;
@@ -119,25 +116,23 @@ pub(crate) fn deserialize(
119116 ElementType :: Uint64 => parse_yy_u64 ( val) ,
120117 ElementType :: Int64 => parse_yy_i64 ( val) ,
121118 ElementType :: Double => parse_yy_f64 ( val) ,
122- ElementType :: Null => parse_none ( ) ,
123- ElementType :: True => parse_true ( ) ,
124- ElementType :: False => parse_false ( ) ,
119+ ElementType :: Null => PyNoneRef :: none ( ) . as_non_null_ptr ( ) ,
120+ ElementType :: True => PyBoolRef :: pytrue ( ) . as_non_null_ptr ( ) ,
121+ ElementType :: False => PyBoolRef :: pyfalse ( ) . as_non_null_ptr ( ) ,
125122 ElementType :: Array | ElementType :: Object => unreachable_unchecked ! ( ) ,
126123 }
127124 } else if is_yyjson_tag ! ( val, TAG_ARRAY ) {
128- let pyval = nonnull ! ( ffi! ( PyList_New ( usize_to_isize ( unsafe_yyjson_get_len( val) ) ) ) ) ;
125+ let pyval = PyListRef :: with_capacity ( unsafe_yyjson_get_len ( val) ) ;
129126 if unsafe_yyjson_get_len ( val) > 0 {
130- populate_yy_array ( pyval. as_ptr ( ) , val) ;
127+ populate_yy_array ( pyval. clone ( ) , val) ;
131128 }
132- pyval
129+ pyval. as_non_null_ptr ( )
133130 } else {
134- let pyval = nonnull ! ( ffi!( _PyDict_NewPresized( usize_to_isize(
135- unsafe_yyjson_get_len( val)
136- ) ) ) ) ;
131+ let pyval = PyDictRef :: with_capacity ( unsafe_yyjson_get_len ( val) ) ;
137132 if unsafe_yyjson_get_len ( val) > 0 {
138- populate_yy_object ( pyval. as_ptr ( ) , val) ;
133+ populate_yy_object ( pyval. clone ( ) , val) ;
139134 }
140- pyval
135+ pyval. as_non_null_ptr ( )
141136 }
142137 } ;
143138 ffi ! ( PyMem_Free ( buffer_ptr) ) ;
@@ -184,54 +179,42 @@ fn parse_yy_string(elem: *mut yyjson_val) -> NonNull<crate::ffi::PyObject> {
184179
185180#[ inline( always) ]
186181fn parse_yy_u64 ( elem : * mut yyjson_val ) -> NonNull < crate :: ffi:: PyObject > {
187- parse_u64 ( unsafe { ( * elem) . uni . u64_ } )
182+ PyIntRef :: from_u64 ( unsafe { ( * elem) . uni . u64_ } ) . as_non_null_ptr ( )
188183}
189184
190185#[ inline( always) ]
191186fn parse_yy_i64 ( elem : * mut yyjson_val ) -> NonNull < crate :: ffi:: PyObject > {
192- parse_i64 ( unsafe { ( * elem) . uni . i64_ } )
187+ PyIntRef :: from_i64 ( unsafe { ( * elem) . uni . i64_ } ) . as_non_null_ptr ( )
193188}
194189
195190#[ inline( always) ]
196191fn parse_yy_f64 ( elem : * mut yyjson_val ) -> NonNull < crate :: ffi:: PyObject > {
197- parse_f64 ( unsafe { ( * elem) . uni . f64_ } )
198- }
199-
200- macro_rules! append_to_list {
201- ( $dptr: expr, $pyval: expr) => {
202- unsafe {
203- core:: ptr:: write( $dptr, $pyval) ;
204- $dptr = $dptr. add( 1 ) ;
205- }
206- } ;
192+ PyFloatRef :: from_f64 ( unsafe { ( * elem) . uni . f64_ } ) . as_non_null_ptr ( )
207193}
208194
209195#[ inline( never) ]
210- fn populate_yy_array ( list : * mut crate :: ffi :: PyObject , elem : * mut yyjson_val ) {
196+ fn populate_yy_array ( mut list : PyListRef , elem : * mut yyjson_val ) {
211197 unsafe {
212198 let len = unsafe_yyjson_get_len ( elem) ;
213199 assume ! ( len >= 1 ) ;
214200 let mut next = unsafe_yyjson_get_first ( elem) ;
215- let mut dptr = ( * list. cast :: < crate :: ffi:: PyListObject > ( ) ) . ob_item ;
216201
217- for _ in 0 ..len {
202+ for idx in 0 ..len {
218203 let val = next;
219204 if unsafe_yyjson_is_ctn ( val) {
220205 cold_path ! ( ) ;
221206 next = unsafe_yyjson_get_next_container ( val) ;
222207 if is_yyjson_tag ! ( val, TAG_ARRAY ) {
223- let pyval = ffi ! ( PyList_New ( usize_to_isize ( unsafe_yyjson_get_len( val) ) ) ) ;
224- append_to_list ! ( dptr , pyval) ;
208+ let pyval = PyListRef :: with_capacity ( unsafe_yyjson_get_len ( val) ) ;
209+ list . set ( idx , pyval. as_ptr ( ) ) ;
225210 if unsafe_yyjson_get_len ( val) > 0 {
226- populate_yy_array ( pyval, val) ;
211+ populate_yy_array ( pyval. clone ( ) , val) ;
227212 }
228213 } else {
229- let pyval = ffi ! ( _PyDict_NewPresized( usize_to_isize( unsafe_yyjson_get_len(
230- val
231- ) ) ) ) ;
232- append_to_list ! ( dptr, pyval) ;
214+ let pyval = PyDictRef :: with_capacity ( unsafe_yyjson_get_len ( val) ) ;
215+ list. set ( idx, pyval. as_ptr ( ) ) ;
233216 if unsafe_yyjson_get_len ( val) > 0 {
234- populate_yy_object ( pyval, val) ;
217+ populate_yy_object ( pyval. clone ( ) , val) ;
235218 }
236219 }
237220 } else {
@@ -241,19 +224,19 @@ fn populate_yy_array(list: *mut crate::ffi::PyObject, elem: *mut yyjson_val) {
241224 ElementType :: Uint64 => parse_yy_u64 ( val) ,
242225 ElementType :: Int64 => parse_yy_i64 ( val) ,
243226 ElementType :: Double => parse_yy_f64 ( val) ,
244- ElementType :: Null => parse_none ( ) ,
245- ElementType :: True => parse_true ( ) ,
246- ElementType :: False => parse_false ( ) ,
227+ ElementType :: Null => PyNoneRef :: none ( ) . as_non_null_ptr ( ) ,
228+ ElementType :: True => PyBoolRef :: pytrue ( ) . as_non_null_ptr ( ) ,
229+ ElementType :: False => PyBoolRef :: pyfalse ( ) . as_non_null_ptr ( ) ,
247230 ElementType :: Array | ElementType :: Object => unreachable_unchecked ! ( ) ,
248231 } ;
249- append_to_list ! ( dptr , pyval. as_ptr( ) ) ;
232+ list . set ( idx , pyval. as_ptr ( ) ) ;
250233 }
251234 }
252235 }
253236}
254237
255238#[ inline( never) ]
256- fn populate_yy_object ( dict : * mut crate :: ffi :: PyObject , elem : * mut yyjson_val ) {
239+ fn populate_yy_object ( mut dict : PyDictRef , elem : * mut yyjson_val ) {
257240 unsafe {
258241 let len = unsafe_yyjson_get_len ( elem) ;
259242 assume ! ( len >= 1 ) ;
@@ -273,18 +256,16 @@ fn populate_yy_object(dict: *mut crate::ffi::PyObject, elem: *mut yyjson_val) {
273256 next_key = unsafe_yyjson_get_next_container ( val) ;
274257 next_val = next_key. add ( 1 ) ;
275258 if is_yyjson_tag ! ( val, TAG_ARRAY ) {
276- let pyval = ffi ! ( PyList_New ( usize_to_isize ( unsafe_yyjson_get_len( val) ) ) ) ;
277- pydict_setitem ! ( dict, pykey . as_ptr( ) , pyval ) ;
259+ let pyval = PyListRef :: with_capacity ( unsafe_yyjson_get_len ( val) ) ;
260+ dict. set ( pykey , pyval . as_ptr ( ) ) ;
278261 if unsafe_yyjson_get_len ( val) > 0 {
279262 populate_yy_array ( pyval, val) ;
280263 }
281264 } else {
282- let pyval = ffi ! ( _PyDict_NewPresized( usize_to_isize( unsafe_yyjson_get_len(
283- val
284- ) ) ) ) ;
285- pydict_setitem ! ( dict, pykey. as_ptr( ) , pyval) ;
265+ let pyval = PyDictRef :: with_capacity ( unsafe_yyjson_get_len ( val) ) ;
266+ dict. set ( pykey, pyval. as_ptr ( ) ) ;
286267 if unsafe_yyjson_get_len ( val) > 0 {
287- populate_yy_object ( pyval, val) ;
268+ populate_yy_object ( pyval. clone ( ) , val) ;
288269 }
289270 }
290271 } else {
@@ -295,12 +276,12 @@ fn populate_yy_object(dict: *mut crate::ffi::PyObject, elem: *mut yyjson_val) {
295276 ElementType :: Uint64 => parse_yy_u64 ( val) ,
296277 ElementType :: Int64 => parse_yy_i64 ( val) ,
297278 ElementType :: Double => parse_yy_f64 ( val) ,
298- ElementType :: Null => parse_none ( ) ,
299- ElementType :: True => parse_true ( ) ,
300- ElementType :: False => parse_false ( ) ,
279+ ElementType :: Null => PyNoneRef :: none ( ) . as_non_null_ptr ( ) ,
280+ ElementType :: True => PyBoolRef :: pytrue ( ) . as_non_null_ptr ( ) ,
281+ ElementType :: False => PyBoolRef :: pyfalse ( ) . as_non_null_ptr ( ) ,
301282 ElementType :: Array | ElementType :: Object => unreachable_unchecked ! ( ) ,
302283 } ;
303- pydict_setitem ! ( dict, pykey . as_ptr ( ) , pyval. as_ptr( ) ) ;
284+ dict. set ( pykey , pyval. as_ptr ( ) ) ;
304285 }
305286 }
306287 }
0 commit comments