diff --git a/src/arbitrary/arbitrary.rs b/src/arbitrary/arbitrary.rs index 5cc8017..08900fa 100644 --- a/src/arbitrary/arbitrary.rs +++ b/src/arbitrary/arbitrary.rs @@ -4,6 +4,7 @@ use ijson::{IArray, INumber, IObject, IString, IValue}; use pyo3::{ exceptions::{PyTypeError, PyValueError}, prelude::*, + types::{PyList, PyNone}, }; use snafu::Snafu; @@ -89,3 +90,24 @@ impl<'py> FromPyObject<'py> for Arbitrary { } } } + +impl<'py> IntoPyObject<'py> for Arbitrary { + type Target = PyAny; + + type Output = Bound<'py, Self::Target>; + + type Error = PyErr; + + fn into_pyobject(self, py: Python<'py>) -> Result { + match self { + Arbitrary::Null => Ok(PyNone::get(py).to_owned().into_any()), + Arbitrary::Bool(b) => Ok(b.into_pyobject(py)?.to_owned().into_any()), + Arbitrary::Integer(i) => Ok(i.into_pyobject(py)?.into_any()), + Arbitrary::Float(finite_f64) => Ok(finite_f64.into_pyobject(py)?.into_any()), + Arbitrary::String(s) => Ok(s.into_pyobject(py)?.into_any()), + Arbitrary::Array(vec) => Ok(PyList::new(py, vec)?.into_any()), + Arbitrary::Map(map) => Ok(map.into_pyobject(py)?.into_any()), + Arbitrary::DateTime(date_time) => Ok(date_time.into_pyobject(py)?.into_any()), + } + } +} diff --git a/src/arbitrary/finite_f64.rs b/src/arbitrary/finite_f64.rs index b5bf69e..3165820 100644 --- a/src/arbitrary/finite_f64.rs +++ b/src/arbitrary/finite_f64.rs @@ -1,6 +1,7 @@ +use pyo3::IntoPyObject; use snafu::Snafu; -#[derive(Debug, Clone, derive_more::Into)] +#[derive(Debug, Clone, derive_more::Into, IntoPyObject)] pub struct FiniteF64(f64); #[derive(Debug, Snafu)] diff --git a/src/arbitrary/map.rs b/src/arbitrary/map.rs index 601152f..a9018f7 100644 --- a/src/arbitrary/map.rs +++ b/src/arbitrary/map.rs @@ -4,12 +4,12 @@ use pyo3::prelude::*; use super::{arbitrary::Arbitrary, map_key::MapKey}; -#[derive(Debug, Clone, derive_more::From, derive_more::Into)] +#[derive(Debug, Clone, Default, derive_more::From, derive_more::Into, IntoPyObject)] pub struct Map(pub BTreeMap); impl<'py> FromPyObject<'py> for Map { fn extract_bound(ob: &Bound<'py, PyAny>) -> PyResult { - let inner: BTreeMap = ob.extract()?; + let inner = ob.extract()?; Ok(Self(inner)) } diff --git a/src/arbitrary/map_key.rs b/src/arbitrary/map_key.rs index 0f57b58..3e71e4b 100644 --- a/src/arbitrary/map_key.rs +++ b/src/arbitrary/map_key.rs @@ -4,7 +4,11 @@ use chrono::DateTime; use chrono_tz::Tz; use ijson::IString; use itertools::Itertools; -use pyo3::{exceptions::PyTypeError, prelude::*, types::PyNone}; +use pyo3::{ + exceptions::PyTypeError, + prelude::*, + types::{PyNone, PyTuple}, +}; use super::arbitrary::{Arbitrary, MapKeyFromArbitraryError}; @@ -58,6 +62,25 @@ impl<'py> FromPyObject<'py> for MapKey { } } +impl<'py> IntoPyObject<'py> for MapKey { + type Target = PyAny; + + type Output = Bound<'py, Self::Target>; + + type Error = PyErr; + + fn into_pyobject(self, py: Python<'py>) -> Result { + match self { + MapKey::Null => Ok(PyNone::get(py).to_owned().into_any()), + MapKey::Bool(b) => Ok(b.into_pyobject(py)?.to_owned().into_any()), + MapKey::Integer(i) => Ok(i.into_pyobject(py)?.into_any()), + MapKey::String(s) => Ok(s.into_pyobject(py)?.into_any()), + MapKey::Tuple(vec) => Ok(PyTuple::new(py, vec)?.into_any()), + MapKey::DateTime(date_time) => Ok(date_time.into_pyobject(py)?.into_any()), + } + } +} + impl From for IString { fn from(map_key: MapKey) -> Self { Self::from(map_key.to_string())