@@ -198,22 +198,6 @@ impl ToPyObject for PythonDTO {
198198}
199199
200200impl PythonDTO {
201- /// Check is it possible to create serde `Value` from `PythonDTO`.
202- #[ must_use]
203- pub fn is_available_to_serde_value ( & self ) -> bool {
204- matches ! (
205- self ,
206- PythonDTO :: PyNone
207- | PythonDTO :: PyBool ( _)
208- | PythonDTO :: PyString ( _)
209- | PythonDTO :: PyText ( _)
210- | PythonDTO :: PyVarChar ( _)
211- | PythonDTO :: PyIntI32 ( _)
212- | PythonDTO :: PyIntI64 ( _)
213- | PythonDTO :: PyFloat32 ( _)
214- | PythonDTO :: PyFloat64 ( _)
215- )
216- }
217201 /// Return type of the Array for `PostgreSQL`.
218202 ///
219203 /// Since every Array must have concrete type,
@@ -285,29 +269,7 @@ impl PythonDTO {
285269
286270 Ok ( json ! ( vec_serde_values) )
287271 }
288- PythonDTO :: PyArray ( array) => Python :: with_gil ( |gil| {
289- if let Some ( array_elem) = array. iter ( ) . nth ( 0 ) {
290- if !array_elem. is_available_to_serde_value ( ) {
291- return Err ( RustPSQLDriverError :: PyToRustValueConversionError (
292- "Your value in dict isn't supported by JSON" . into ( ) ,
293- ) ) ;
294- }
295- }
296- let py_list = postgres_array_to_py ( gil, Some ( array. clone ( ) ) ) ;
297- if let Some ( py_list) = py_list {
298- let mut vec_serde_values: Vec < Value > = vec ! [ ] ;
299-
300- for py_object in py_list. bind ( gil) {
301- vec_serde_values. push ( py_to_rust ( & py_object) ?. to_serde_value ( ) ?) ;
302- }
303-
304- return Ok ( json ! ( vec_serde_values) ) ;
305- }
306-
307- Err ( RustPSQLDriverError :: PyToRustValueConversionError (
308- "Cannot convert Python sequence into JSON" . into ( ) ,
309- ) )
310- } ) ,
272+ PythonDTO :: PyArray ( array) => Ok ( json ! ( pythondto_array_to_serde( Some ( array. clone( ) ) ) ?) ) ,
311273 PythonDTO :: PyJsonb ( py_dict) | PythonDTO :: PyJson ( py_dict) => Ok ( py_dict. clone ( ) ) ,
312274 _ => Err ( RustPSQLDriverError :: PyToRustValueConversionError (
313275 "Cannot convert your type into Rust type" . into ( ) ,
@@ -848,6 +810,62 @@ fn _composite_field_postgres_to_py<'a, T: FromSql<'a>>(
848810 } )
849811}
850812
813+ /// Convert Array of `PythonDTO`s to serde `Value`.
814+ ///
815+ /// It can convert multidimensional arrays.
816+ fn pythondto_array_to_serde ( array : Option < Array < PythonDTO > > ) -> RustPSQLDriverPyResult < Value > {
817+ match array {
818+ Some ( array) => {
819+ return _pythondto_array_to_serde (
820+ array. dimensions ( ) ,
821+ array. iter ( ) . collect :: < Vec < & PythonDTO > > ( ) . as_slice ( ) ,
822+ 0 ,
823+ 0 ,
824+ ) ;
825+ }
826+ None => Ok ( Value :: Null ) ,
827+ }
828+ }
829+
830+ /// Inner conversion array of `PythonDTO`s to serde `Value`.
831+ #[ allow( clippy:: cast_sign_loss) ]
832+ fn _pythondto_array_to_serde (
833+ dimensions : & [ Dimension ] ,
834+ data : & [ & PythonDTO ] ,
835+ dimension_index : usize ,
836+ mut lower_bound : usize ,
837+ ) -> RustPSQLDriverPyResult < Value > {
838+ let current_dimension = dimensions. get ( dimension_index) . unwrap ( ) ;
839+
840+ let possible_next_dimension = dimensions. get ( dimension_index + 1 ) ;
841+ match possible_next_dimension {
842+ Some ( next_dimension) => {
843+ let mut final_list: Value = Value :: Array ( vec ! [ ] ) ;
844+
845+ for _ in 0 ..current_dimension. len as usize {
846+ if dimensions. get ( dimension_index + 1 ) . is_some ( ) {
847+ let inner_pylist = _pythondto_array_to_serde (
848+ dimensions,
849+ & data[ lower_bound..next_dimension. len as usize + lower_bound] ,
850+ dimension_index + 1 ,
851+ 0 ,
852+ ) ?;
853+ match final_list {
854+ Value :: Array ( ref mut array) => array. push ( inner_pylist) ,
855+ _ => unreachable ! ( ) ,
856+ }
857+ lower_bound += next_dimension. len as usize ;
858+ } ;
859+ }
860+
861+ Ok ( final_list)
862+ }
863+ None => {
864+ return data. iter ( ) . map ( |x| x. to_serde_value ( ) ) . collect ( ) ;
865+ }
866+ }
867+ }
868+
851869/// Convert rust array to python list.
852870///
853871/// It can convert multidimensional arrays.
0 commit comments