2017-05-29 04:19:29 +00:00
|
|
|
// Copyright (c) 2017-present PyO3 Project and Contributors
|
|
|
|
|
2017-06-01 16:45:00 +00:00
|
|
|
use std::rc::Rc;
|
2017-05-29 04:19:29 +00:00
|
|
|
use std::marker::PhantomData;
|
|
|
|
|
2017-06-04 00:27:26 +00:00
|
|
|
use ffi;
|
2017-06-02 16:23:48 +00:00
|
|
|
use err::PyResult;
|
2017-06-04 00:27:26 +00:00
|
|
|
use python::{Python, IntoPyPointer};
|
2017-05-29 04:19:29 +00:00
|
|
|
use typeob::{PyTypeInfo, PyObjectAlloc};
|
|
|
|
|
|
|
|
|
2017-06-01 22:06:48 +00:00
|
|
|
pub struct PyToken(PhantomData<Rc<()>>);
|
2017-05-29 04:19:29 +00:00
|
|
|
|
2017-06-01 22:06:48 +00:00
|
|
|
impl PyToken {
|
2017-06-11 15:46:23 +00:00
|
|
|
pub fn token(&self) -> Python {
|
2017-05-29 04:19:29 +00:00
|
|
|
unsafe { Python::assume_gil_acquired() }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-06-04 00:27:26 +00:00
|
|
|
/// Create new python object and move T instance under python management
|
2017-05-29 04:19:29 +00:00
|
|
|
#[inline]
|
2017-06-11 15:46:23 +00:00
|
|
|
pub fn init<T, F>(py: Python, f: F) -> PyResult<T::Target>
|
2017-06-01 22:06:48 +00:00
|
|
|
where F: FnOnce(PyToken) -> T,
|
2017-06-09 21:27:37 +00:00
|
|
|
T: ToInstancePtr<T> + PyTypeInfo + PyObjectAlloc<T>
|
2017-05-29 04:19:29 +00:00
|
|
|
{
|
2017-06-04 00:27:26 +00:00
|
|
|
let ob = f(PyToken(PhantomData));
|
|
|
|
|
|
|
|
let ob = unsafe {
|
2017-06-09 21:27:37 +00:00
|
|
|
let ob = try!(<T as PyObjectAlloc<T>>::alloc(py, ob));
|
2017-06-04 00:27:26 +00:00
|
|
|
T::from_owned_ptr(ob)
|
|
|
|
};
|
|
|
|
Ok(ob)
|
2017-05-29 04:19:29 +00:00
|
|
|
}
|
|
|
|
|
2017-06-01 22:06:48 +00:00
|
|
|
pub trait PyObjectWithToken : Sized {
|
2017-06-11 15:46:23 +00:00
|
|
|
fn token(&self) -> Python;
|
2017-05-29 04:19:29 +00:00
|
|
|
}
|
2017-06-04 00:27:26 +00:00
|
|
|
|
2017-06-06 03:25:00 +00:00
|
|
|
pub trait ToInstancePtr<T> : Sized {
|
|
|
|
type Target: InstancePtr<T> + IntoPyPointer;
|
2017-06-04 00:27:26 +00:00
|
|
|
|
2017-06-06 03:25:00 +00:00
|
|
|
fn to_inst_ptr(&self) -> Self::Target;
|
2017-06-04 00:27:26 +00:00
|
|
|
|
2017-06-06 03:25:00 +00:00
|
|
|
unsafe fn from_owned_ptr(*mut ffi::PyObject) -> Self::Target;
|
2017-06-04 00:27:26 +00:00
|
|
|
|
2017-06-06 03:25:00 +00:00
|
|
|
unsafe fn from_borrowed_ptr(*mut ffi::PyObject) -> Self::Target;
|
2017-06-04 00:27:26 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-06-06 03:25:00 +00:00
|
|
|
pub trait InstancePtr<T> : Sized {
|
2017-06-04 00:27:26 +00:00
|
|
|
|
|
|
|
fn as_ref(&self, py: Python) -> &T;
|
|
|
|
|
|
|
|
fn as_mut(&self, py: Python) -> &mut T;
|
|
|
|
|
2017-06-06 03:25:00 +00:00
|
|
|
fn with<F, R>(&self, f: F) -> R where F: FnOnce(Python, &T) -> R
|
|
|
|
{
|
|
|
|
let gil = Python::acquire_gil();
|
|
|
|
let py = gil.python();
|
|
|
|
|
|
|
|
f(py, self.as_ref(py))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn with_mut<F, R>(&self, f: F) -> R where F: FnOnce(Python, &mut T) -> R
|
|
|
|
{
|
|
|
|
let gil = Python::acquire_gil();
|
|
|
|
let py = gil.python();
|
|
|
|
|
|
|
|
f(py, self.as_mut(py))
|
|
|
|
}
|
2017-06-07 02:26:59 +00:00
|
|
|
|
|
|
|
fn into_py<F, R>(self, f: F) -> R
|
|
|
|
where Self: IntoPyPointer, F: FnOnce(Python, &T) -> R
|
|
|
|
{
|
|
|
|
let gil = Python::acquire_gil();
|
|
|
|
let py = gil.python();
|
|
|
|
|
|
|
|
let result = f(py, self.as_ref(py));
|
|
|
|
py.release(self);
|
|
|
|
result
|
|
|
|
}
|
|
|
|
|
|
|
|
fn into_mut_py<F, R>(self, f: F) -> R
|
|
|
|
where Self: IntoPyPointer, F: FnOnce(Python, &mut T) -> R
|
|
|
|
{
|
|
|
|
let gil = Python::acquire_gil();
|
|
|
|
let py = gil.python();
|
|
|
|
|
|
|
|
let result = f(py, self.as_mut(py));
|
|
|
|
py.release(self);
|
|
|
|
result
|
|
|
|
}
|
2017-06-04 00:27:26 +00:00
|
|
|
}
|