I imagine you have to construct some dynamic Python object. With Rust you can't use enums with fields and you can't use types with generic parameters. I think you can construct a python dictionary (or class if you prefer that, though this requires more effort and writing that class in Python, I assume). What I'd do is construct a dictionary with the fields type
and value
, for example:
d1 = {
"type": "str",
"value": "hello",
}
d2 = {
"type": "bool",
"value": True,
}
I think this can be accomplished by implementing the ToPyObject
trait for Prop
, something like this:
use pyo3::conversion::ToPyObject;
use pyo3::{types::PyDict, PyObject, Python};
pub enum Prop {
Str(String),
I32(i32),
I64(i64),
U32(u32),
U64(u64),
F32(f32),
F64(f64),
Bool(bool),
}
impl Prop {
fn ty(&self) -> String {
match self {
Self::Str(_) => "str",
Self::I32(_) => "i32",
Self::I64(_) => "i64",
Self::U32(_) => "u32",
Self::U64(_) => "u64",
Self::F32(_) => "f32",
Self::F64(_) => "f64",
Self::Bool(_) => "bool",
}
.to_owned()
}
fn value(&self) -> PyObject {
Python::with_gil(|py| match self {
Self::Str(s) => s.to_object(py),
Self::I32(i) => i.to_object(py),
Self::I64(i) => i.to_object(py),
Self::U32(u) => u.to_object(py),
Self::U64(u) => u.to_object(py),
Self::F32(f) => f.to_object(py),
Self::F64(f) => f.to_object(py),
Self::Bool(b) => b.to_object(py),
})
}
}
impl ToPyObject for Prop {
fn to_object(&self, py: Python<'_>) -> PyObject {
let obj = PyDict::new(py);
obj.set_item("type", self.ty()).unwrap();
obj.set_item("value", self.value()).unwrap();
obj.into()
}
}
I didn't test it, so try out with caution.