use std;
use ffi;
use python::{Python, PythonObject, PythonObjectWithCheckedDowncast, PyClone};
use objects::PyObject;
use err::PyResult;
pub trait ToPyObject {
type ObjectType : PythonObject;
fn to_py_object(&self, py: Python) -> Self::ObjectType;
#[inline]
fn into_py_object(self, py: Python) -> Self::ObjectType
where Self: Sized
{
self.to_py_object(py)
}
#[inline]
fn with_borrowed_ptr<F, R>(&self, py: Python, f: F) -> R
where F: FnOnce(*mut ffi::PyObject) -> R
{
let obj = self.to_py_object(py).into_object();
f(obj.as_ptr())
}
}
py_impl_to_py_object_for_python_object!(PyObject);
pub trait FromPyObject<'source> : Sized {
fn extract(py: Python, obj: &'source PyObject) -> PyResult<Self>;
}
py_impl_from_py_object_for_python_object!(PyObject);
pub trait RefFromPyObject {
fn with_extracted<F, R>(py: Python, obj: &PyObject, f: F) -> PyResult<R>
where F: FnOnce(&Self) -> R;
}
impl <T: ?Sized> RefFromPyObject for T
where for<'a> &'a T: FromPyObject<'a>
{
#[inline]
fn with_extracted<F, R>(py: Python, obj: &PyObject, f: F) -> PyResult<R>
where F: FnOnce(&Self) -> R
{
match FromPyObject::extract(py, obj) {
Ok(val) => Ok(f(val)),
Err(e) => Err(e)
}
}
}
impl <'a, T: ?Sized> ToPyObject for &'a T where T: ToPyObject {
type ObjectType = T::ObjectType;
#[inline]
fn to_py_object(&self, py: Python) -> T::ObjectType {
<T as ToPyObject>::to_py_object(*self, py)
}
#[inline]
fn into_py_object(self, py: Python) -> T::ObjectType {
<T as ToPyObject>::to_py_object(self, py)
}
#[inline]
fn with_borrowed_ptr<F, R>(&self, py: Python, f: F) -> R
where F: FnOnce(*mut ffi::PyObject) -> R
{
<T as ToPyObject>::with_borrowed_ptr(*self, py, f)
}
}
impl <T> ToPyObject for Option<T> where T: ToPyObject {
type ObjectType = PyObject;
fn to_py_object(&self, py: Python) -> PyObject {
match *self {
Some(ref val) => val.to_py_object(py).into_object(),
None => py.None()
}
}
fn into_py_object(self, py: Python) -> PyObject {
match self {
Some(val) => val.into_py_object(py).into_object(),
None => py.None()
}
}
}
impl <'source, T> FromPyObject<'source> for Option<T> where T: FromPyObject<'source> {
fn extract(py: Python, obj: &'source PyObject) -> PyResult<Self> {
if obj.as_ptr() == unsafe { ffi::Py_None() } {
Ok(None)
} else {
match T::extract(py, obj) {
Ok(v) => Ok(Some(v)),
Err(e) => Err(e)
}
}
}
}