use pyo3::BoundObject;
use pyo3::prelude::*;
use pyo3::types::PyList;
pub trait ToJsonDict {
fn to_json_dict(&self, py: Python<'_>) -> PyResult<Py<PyAny>>;
}
macro_rules! to_json_primitive {
($t:ty) => {
impl $crate::to_json_dict::ToJsonDict for $t {
fn to_json_dict(&self, py: Python<'_>) -> pyo3::PyResult<Py<PyAny>> {
Ok(self.into_pyobject(py)?.into_any().unbind())
}
}
};
}
to_json_primitive!(bool);
to_json_primitive!(u8);
to_json_primitive!(i8);
to_json_primitive!(u16);
to_json_primitive!(i16);
to_json_primitive!(u32);
to_json_primitive!(i32);
to_json_primitive!(u64);
to_json_primitive!(i64);
to_json_primitive!(u128);
to_json_primitive!(i128);
to_json_primitive!(String);
impl<T: ToJsonDict> ToJsonDict for Vec<T> {
fn to_json_dict(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let list = PyList::empty(py);
for v in self {
list.append(v.to_json_dict(py)?)?;
}
Ok(list.into())
}
}
impl<T: ToJsonDict> ToJsonDict for Option<T> {
fn to_json_dict(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
match self {
None => Ok(py.None()),
Some(v) => Ok(v.to_json_dict(py)?),
}
}
}
impl<T: ToJsonDict, U: ToJsonDict> ToJsonDict for (T, U) {
fn to_json_dict(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let list = PyList::empty(py);
list.append(self.0.to_json_dict(py)?)?;
list.append(self.1.to_json_dict(py)?)?;
Ok(list.into())
}
}
impl<T: ToJsonDict, U: ToJsonDict, W: ToJsonDict> ToJsonDict for (T, U, W) {
fn to_json_dict(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let list = PyList::empty(py);
list.append(self.0.to_json_dict(py)?)?;
list.append(self.1.to_json_dict(py)?)?;
list.append(self.2.to_json_dict(py)?)?;
Ok(list.into())
}
}
impl<T: ToJsonDict, const N: usize> ToJsonDict for [T; N] {
fn to_json_dict(&self, py: Python<'_>) -> PyResult<Py<PyAny>> {
let list = PyList::empty(py);
for v in self {
list.append(v.to_json_dict(py)?)?;
}
Ok(list.into())
}
}