pconvert_rust/pymodule/
conversions.rs

1//! From and to conversions for rust and python types.
2
3use crate::blending::params::Value;
4use crate::errors::PConvertError;
5use crate::parallelism::ThreadPoolStatus;
6use pyo3::conversion::FromPyObject;
7use pyo3::exceptions::{
8    PyAttributeError, PyException, PyIOError, PyNotImplementedError, PyTypeError,
9};
10use pyo3::prelude::*;
11use pyo3::types::{IntoPyDict, PyBool, PyDict, PyFloat, PyInt, PyLong, PyString};
12use pyo3::PyErr;
13
14impl From<PConvertError> for PyErr {
15    fn from(err: PConvertError) -> PyErr {
16        match err {
17            PConvertError::ArgumentError(err) => PyAttributeError::new_err(err),
18            PConvertError::ImageLibError(err) => PyException::new_err(err.to_string()),
19            PConvertError::UnsupportedImageTypeError => {
20                PyNotImplementedError::new_err(err.to_string())
21            }
22            PConvertError::IOError(err) => PyIOError::new_err(err.to_string()),
23        }
24    }
25}
26
27impl FromPyObject<'_> for Value {
28    fn extract(ob: &'_ PyAny) -> PyResult<Self> {
29        if let Ok(boolean) = ob.cast_as::<PyBool>() {
30            let boolean = boolean.is_true();
31            Ok(Value::Bool(boolean))
32        } else if let Ok(float) = ob.cast_as::<PyFloat>() {
33            let float = float.value();
34            Ok(Value::Float(float))
35        } else if let Ok(int) = ob.cast_as::<PyInt>() {
36            let int = int.extract::<i32>()?;
37            Ok(Value::Int(int))
38        } else if let Ok(long) = ob.cast_as::<PyLong>() {
39            let long = long.extract::<i64>()?;
40            Ok(Value::Long(long))
41        } else if let Ok(string) = ob.cast_as::<PyString>() {
42            let string = string.to_string();
43            Ok(Value::Str(string))
44        } else {
45            let msg = format!("Failure converting {}", ob);
46            Err(PyTypeError::new_err(msg))
47        }
48    }
49}
50
51impl IntoPyDict for ThreadPoolStatus {
52    fn into_py_dict(self, py: Python<'_>) -> &PyDict {
53        let py_dict = PyDict::new(py);
54
55        py_dict.set_item("size", self.size()).unwrap();
56        py_dict.set_item("queued", self.queued()).unwrap();
57        py_dict.set_item("active", self.active()).unwrap();
58
59        py_dict
60    }
61}