#[cfg(feature = "python")]
use pyo3::prelude::*;
#[cfg(feature = "python")]
pub trait FromPyMessage: Sized {
fn from_py(obj: &Bound<'_, PyAny>) -> PyResult<Self>;
}
#[cfg(feature = "python")]
#[allow(clippy::wrong_self_convention)]
pub trait IntoPyMessage {
fn into_py_message(&self, py: Python) -> PyResult<PyObject>;
}
#[cfg(feature = "python")]
macro_rules! impl_from_py_primitive {
($($ty:ty),*) => {
$(
impl FromPyMessage for $ty {
fn from_py(obj: &Bound<'_, PyAny>) -> PyResult<Self> {
obj.extract()
}
}
)*
};
}
#[cfg(feature = "python")]
impl_from_py_primitive!(bool, i8, u8, i16, u16, i32, u32, i64, u64, f32, f64);
#[cfg(feature = "python")]
impl FromPyMessage for String {
fn from_py(obj: &Bound<'_, PyAny>) -> PyResult<Self> {
obj.extract()
}
}
#[cfg(feature = "python")]
impl FromPyMessage for Vec<u8> {
fn from_py(obj: &Bound<'_, PyAny>) -> PyResult<Self> {
if let Ok(bytes) = obj.downcast::<pyo3::types::PyBytes>() {
return Ok(bytes.as_bytes().to_vec());
}
if let Ok(bytearray) = obj.downcast::<pyo3::types::PyByteArray>() {
return Ok(unsafe { bytearray.as_bytes() }.to_vec());
}
obj.extract()
}
}
#[cfg(feature = "python")]
impl<T: FromPyMessage + FromPyMessageNotU8> FromPyMessage for Vec<T> {
fn from_py(obj: &Bound<'_, PyAny>) -> PyResult<Self> {
let mut result = Vec::new();
for item in obj.iter()? {
result.push(T::from_py(&item?)?);
}
Ok(result)
}
}
#[cfg(feature = "python")]
pub trait FromPyMessageNotU8 {}
#[cfg(feature = "python")]
impl FromPyMessageNotU8 for bool {}
#[cfg(feature = "python")]
impl FromPyMessageNotU8 for i8 {}
#[cfg(feature = "python")]
impl FromPyMessageNotU8 for i16 {}
#[cfg(feature = "python")]
impl FromPyMessageNotU8 for u16 {}
#[cfg(feature = "python")]
impl FromPyMessageNotU8 for i32 {}
#[cfg(feature = "python")]
impl FromPyMessageNotU8 for u32 {}
#[cfg(feature = "python")]
impl FromPyMessageNotU8 for i64 {}
#[cfg(feature = "python")]
impl FromPyMessageNotU8 for u64 {}
#[cfg(feature = "python")]
impl FromPyMessageNotU8 for f32 {}
#[cfg(feature = "python")]
impl FromPyMessageNotU8 for f64 {}
#[cfg(feature = "python")]
impl FromPyMessageNotU8 for String {}
#[cfg(feature = "python")]
impl<T> FromPyMessageNotU8 for Vec<T> {}
#[cfg(feature = "python")]
impl<T, const N: usize> FromPyMessageNotU8 for [T; N] {}
#[cfg(feature = "python")]
macro_rules! impl_into_py_primitive {
($($ty:ty),*) => {
$(
impl IntoPyMessage for $ty {
fn into_py_message(&self, py: Python) -> PyResult<PyObject> {
use pyo3::ToPyObject;
Ok(self.to_object(py))
}
}
)*
};
}
#[cfg(feature = "python")]
impl_into_py_primitive!(bool, i8, u8, i16, u16, i32, u32, i64, u64, f32, f64);
#[cfg(feature = "python")]
impl IntoPyMessage for String {
fn into_py_message(&self, py: Python) -> PyResult<PyObject> {
use pyo3::ToPyObject;
Ok(self.to_object(py))
}
}
#[cfg(feature = "python")]
impl IntoPyMessage for Vec<u8> {
fn into_py_message(&self, py: Python) -> PyResult<PyObject> {
Ok(pyo3::types::PyBytes::new_bound(py, self).into())
}
}
#[cfg(feature = "python")]
impl<T: IntoPyMessage + IntoPyMessageNotU8> IntoPyMessage for Vec<T> {
fn into_py_message(&self, py: Python) -> PyResult<PyObject> {
let list = pyo3::types::PyList::empty_bound(py);
for item in self {
list.append(item.into_py_message(py)?)?;
}
Ok(list.into())
}
}
#[cfg(feature = "python")]
pub trait IntoPyMessageNotU8 {}
#[cfg(feature = "python")]
impl IntoPyMessageNotU8 for bool {}
#[cfg(feature = "python")]
impl IntoPyMessageNotU8 for i8 {}
#[cfg(feature = "python")]
impl IntoPyMessageNotU8 for i16 {}
#[cfg(feature = "python")]
impl IntoPyMessageNotU8 for u16 {}
#[cfg(feature = "python")]
impl IntoPyMessageNotU8 for i32 {}
#[cfg(feature = "python")]
impl IntoPyMessageNotU8 for u32 {}
#[cfg(feature = "python")]
impl IntoPyMessageNotU8 for i64 {}
#[cfg(feature = "python")]
impl IntoPyMessageNotU8 for u64 {}
#[cfg(feature = "python")]
impl IntoPyMessageNotU8 for f32 {}
#[cfg(feature = "python")]
impl IntoPyMessageNotU8 for f64 {}
#[cfg(feature = "python")]
impl IntoPyMessageNotU8 for String {}
#[cfg(feature = "python")]
impl<T> IntoPyMessageNotU8 for Vec<T> {}
#[cfg(feature = "python")]
impl<T, const N: usize> IntoPyMessageNotU8 for [T; N] {}
#[cfg(not(feature = "python"))]
pub trait FromPyMessage: Sized {}
#[cfg(not(feature = "python"))]
pub trait IntoPyMessage {}