Python: Expose Slint structs

Structs declared and exported in Slint are now available in the module namespace
with a constructor.

Fixes #5708
This commit is contained in:
Simon Hausmann 2024-07-08 22:20:29 +02:00 committed by Simon Hausmann
parent 048c0eaf08
commit 1e3f05c983
11 changed files with 144 additions and 12 deletions

View file

@ -8,6 +8,8 @@ use std::rc::Rc;
use slint_interpreter::{ComponentHandle, Value};
use i_slint_compiler::langtype::Type;
use indexmap::IndexMap;
use pyo3::gc::PyVisit;
use pyo3::prelude::*;
@ -17,7 +19,7 @@ use pyo3::PyTraverseError;
use crate::errors::{
PyGetPropertyError, PyInvokeError, PyPlatformError, PySetCallbackError, PySetPropertyError,
};
use crate::value::PyValue;
use crate::value::{PyStruct, PyValue};
#[pyclass(unsendable)]
pub struct Compiler {
@ -143,6 +145,40 @@ impl CompilationResult {
fn get_diagnostics(&self) -> Vec<PyDiagnostic> {
self.result.diagnostics().map(|diag| PyDiagnostic(diag.clone())).collect()
}
#[getter]
fn structs_and_enums(&self, py: Python<'_>) -> HashMap<String, PyObject> {
let structs_and_enums =
self.result.structs_and_enums(i_slint_core::InternalToken {}).collect::<Vec<_>>();
fn convert_type(py: Python<'_>, ty: &Type) -> Option<(String, PyObject)> {
match ty {
Type::Struct { fields, name: Some(name), node: Some(_), .. } => {
let struct_instance = PyStruct::from(slint_interpreter::Struct::from_iter(
fields.iter().map(|(name, field_type)| {
(
name.to_string(),
slint_interpreter::default_value_for_type(field_type),
)
}),
));
return Some((name.to_string(), struct_instance.into_py(py)));
}
Type::Enumeration(_en) => {
// TODO
}
_ => {}
}
None
}
structs_and_enums
.iter()
.filter_map(|ty| convert_type(py, ty))
.into_iter()
.collect::<HashMap<String, PyObject>>()
}
}
#[pyclass(unsendable)]