Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 8f6c0f3

Browse filesBrowse files
committed
Fixed problem with arrays in JSONs
Signed-off-by: chandr-andr (Kiselev Aleksandr) <chandr@chandr.net>
1 parent 1244078 commit 8f6c0f3
Copy full SHA for 8f6c0f3

File tree

Expand file treeCollapse file tree

1 file changed

+57
-39
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+57
-39
lines changed

‎src/value_converter.rs

Copy file name to clipboardExpand all lines: src/value_converter.rs
+57-39Lines changed: 57 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -198,22 +198,6 @@ impl ToPyObject for PythonDTO {
198198
}
199199

200200
impl 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 rust array to python list.
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 postgres array conversion to python list.
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

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.