mirror of
https://github.com/slint-ui/slint.git
synced 2025-12-15 21:45:24 +00:00
Python: Add support for converting structs
They map to Python dicts. cc #4202
This commit is contained in:
parent
d486012bcf
commit
b4cddbbe18
2 changed files with 63 additions and 21 deletions
|
|
@ -2,26 +2,32 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
|
||||
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::types::{IntoPyDict, PyDict};
|
||||
|
||||
pub struct PyValue(pub slint_interpreter::Value);
|
||||
struct PyValueRef<'a>(&'a slint_interpreter::Value);
|
||||
|
||||
impl IntoPy<PyObject> for PyValue {
|
||||
fn into_py(self, py: Python<'_>) -> PyObject {
|
||||
match self.0 {
|
||||
slint_interpreter::Value::Void => ().into_py(py),
|
||||
slint_interpreter::Value::Number(num) => num.into_py(py),
|
||||
slint_interpreter::Value::String(str) => str.into_py(py),
|
||||
slint_interpreter::Value::Bool(b) => b.into_py(py),
|
||||
slint_interpreter::Value::Image(_) => todo!(),
|
||||
slint_interpreter::Value::Model(_) => todo!(),
|
||||
slint_interpreter::Value::Struct(_) => todo!(),
|
||||
slint_interpreter::Value::Brush(_) => todo!(),
|
||||
_ => todo!(),
|
||||
}
|
||||
// Share the conversion code below that operates on the reference
|
||||
self.to_object(py).into_py(py)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToPyObject for PyValue {
|
||||
fn to_object(&self, py: Python<'_>) -> PyObject {
|
||||
PyValueRef(&self.0).to_object(py)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoPy<PyObject> for PyValueRef<'a> {
|
||||
fn into_py(self, py: Python<'_>) -> PyObject {
|
||||
// Share the conversion code below that operates on the reference
|
||||
self.to_object(py).into_py(py)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ToPyObject for PyValueRef<'a> {
|
||||
fn to_object(&self, py: Python<'_>) -> PyObject {
|
||||
match &self.0 {
|
||||
slint_interpreter::Value::Void => ().into_py(py),
|
||||
|
|
@ -30,7 +36,11 @@ impl ToPyObject for PyValue {
|
|||
slint_interpreter::Value::Bool(b) => b.into_py(py),
|
||||
slint_interpreter::Value::Image(_) => todo!(),
|
||||
slint_interpreter::Value::Model(_) => todo!(),
|
||||
slint_interpreter::Value::Struct(_) => todo!(),
|
||||
slint_interpreter::Value::Struct(structval) => structval
|
||||
.iter()
|
||||
.map(|(name, val)| (name.to_string().into_py(py), PyValueRef(val).into_py(py)))
|
||||
.into_py_dict(py)
|
||||
.into_py(py),
|
||||
slint_interpreter::Value::Brush(_) => todo!(),
|
||||
_ => todo!(),
|
||||
}
|
||||
|
|
@ -43,16 +53,30 @@ impl FromPyObject<'_> for PyValue {
|
|||
return Ok(slint_interpreter::Value::Void.into());
|
||||
}
|
||||
|
||||
Ok(PyValue(
|
||||
ob.extract::<bool>()
|
||||
.map(|b| slint_interpreter::Value::Bool(b))
|
||||
.or_else(|_| {
|
||||
ob.extract::<&'_ str>().map(|s| slint_interpreter::Value::String(s.into()))
|
||||
let interpreter_val = ob
|
||||
.extract::<bool>()
|
||||
.map(|b| slint_interpreter::Value::Bool(b))
|
||||
.or_else(|_| {
|
||||
ob.extract::<&'_ str>().map(|s| slint_interpreter::Value::String(s.into()))
|
||||
})
|
||||
.or_else(|_| ob.extract::<f64>().map(|num| slint_interpreter::Value::Number(num)))
|
||||
.or_else(|_| {
|
||||
ob.extract::<&PyDict>().and_then(|dict| {
|
||||
let dict_items: Result<Vec<(String, slint_interpreter::Value)>, PyErr> = dict
|
||||
.iter()
|
||||
.map(|(name, pyval)| {
|
||||
let name = name.extract::<&str>()?.to_string();
|
||||
let slintval: PyValue = pyval.extract()?;
|
||||
Ok((name, slintval.0))
|
||||
})
|
||||
.collect::<Result<Vec<(_, _)>, PyErr>>();
|
||||
Ok(slint_interpreter::Value::Struct(slint_interpreter::Struct::from_iter(
|
||||
dict_items?.into_iter(),
|
||||
)))
|
||||
})
|
||||
.or_else(|_| {
|
||||
ob.extract::<f64>().map(|num| slint_interpreter::Value::Number(num))
|
||||
})?,
|
||||
))
|
||||
})?;
|
||||
|
||||
Ok(PyValue(interpreter_val))
|
||||
}
|
||||
}
|
||||
impl From<slint_interpreter::Value> for PyValue {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue