impl PyNativeFuncInternal for &Py<Self> form

This commit is contained in:
Jeong YunWon
2023-03-16 19:37:25 +09:00
parent f314328294
commit 1fda3ba969
3 changed files with 88 additions and 4 deletions

View File

@@ -1,6 +1,7 @@
use super::{FromArgs, FuncArgs};
use crate::{
convert::ToPyResult, object::PyThreadingConstraint, PyPayload, PyRef, PyResult, VirtualMachine,
convert::ToPyResult, object::PyThreadingConstraint, Py, PyPayload, PyRef, PyResult,
VirtualMachine,
};
use std::marker::PhantomData;
@@ -59,6 +60,8 @@ use sealed::PyNativeFuncInternal;
#[doc(hidden)]
pub struct OwnedParam<T>(PhantomData<T>);
#[doc(hidden)]
pub struct BorrowedParam<T>(PhantomData<T>);
#[doc(hidden)]
pub struct RefParam<T>(PhantomData<T>);
// This is the "magic" that allows rust functions of varying signatures to
@@ -80,6 +83,20 @@ macro_rules! into_py_native_func_tuple {
}
}
impl<F, S, $($T,)* R> PyNativeFuncInternal<(BorrowedParam<S>, $(OwnedParam<$T>,)*), R, VirtualMachine> for F
where
F: Fn(&Py<S>, $($T,)* &VirtualMachine) -> R + PyThreadingConstraint + 'static,
S: PyPayload,
$($T: FromArgs,)*
R: ToPyResult,
{
fn call_(&self, vm: &VirtualMachine, args: FuncArgs) -> PyResult {
let (zelf, $($n,)*) = args.bind::<(PyRef<S>, $($T,)*)>(vm)?;
(self)(&zelf, $($n,)* vm).to_pyresult(vm)
}
}
impl<F, S, $($T,)* R> PyNativeFuncInternal<(RefParam<S>, $(OwnedParam<$T>,)*), R, VirtualMachine> for F
where
F: Fn(&S, $($T,)* &VirtualMachine) -> R + PyThreadingConstraint + 'static,
@@ -107,6 +124,20 @@ macro_rules! into_py_native_func_tuple {
}
}
impl<F, S, $($T,)* R> PyNativeFuncInternal<(BorrowedParam<S>, $(OwnedParam<$T>,)*), R, ()> for F
where
F: Fn(&Py<S>, $($T,)*) -> R + PyThreadingConstraint + 'static,
S: PyPayload,
$($T: FromArgs,)*
R: ToPyResult,
{
fn call_(&self, vm: &VirtualMachine, args: FuncArgs) -> PyResult {
let (zelf, $($n,)*) = args.bind::<(PyRef<S>, $($T,)*)>(vm)?;
(self)(&zelf, $($n,)*).to_pyresult(vm)
}
}
impl<F, S, $($T,)* R> PyNativeFuncInternal<(RefParam<S>, $(OwnedParam<$T>,)*), R, ()> for F
where
F: Fn(&S, $($T,)*) -> R + PyThreadingConstraint + 'static,

View File

@@ -3,9 +3,9 @@
*/
use crate::{
convert::ToPyResult,
function::{OwnedParam, RefParam},
function::{BorrowedParam, OwnedParam, RefParam},
object::PyThreadingConstraint,
PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine,
Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine,
};
#[derive(result_like::OptionLike, is_macro::Is, Debug)]
@@ -74,6 +74,18 @@ where
}
}
impl<F, S, R> IntoPyGetterFunc<(BorrowedParam<S>, R, VirtualMachine)> for F
where
F: Fn(&Py<S>, &VirtualMachine) -> R + 'static + Send + Sync,
S: PyPayload,
R: ToPyResult,
{
fn get(&self, obj: PyObjectRef, vm: &VirtualMachine) -> PyResult {
let zelf = PyRef::<S>::try_from_object(vm, obj)?;
(self)(&zelf, vm).to_pyresult(vm)
}
}
impl<F, S, R> IntoPyGetterFunc<(RefParam<S>, R, VirtualMachine)> for F
where
F: Fn(&S, &VirtualMachine) -> R + 'static + Send + Sync,
@@ -98,6 +110,18 @@ where
}
}
impl<F, S, R> IntoPyGetterFunc<(BorrowedParam<S>, R)> for F
where
F: Fn(&Py<S>) -> R + 'static + Send + Sync,
S: PyPayload,
R: ToPyResult,
{
fn get(&self, obj: PyObjectRef, vm: &VirtualMachine) -> PyResult {
let zelf = PyRef::<S>::try_from_object(vm, obj)?;
(self)(&zelf).to_pyresult(vm)
}
}
impl<F, S, R> IntoPyGetterFunc<(RefParam<S>, R)> for F
where
F: Fn(&S) -> R + 'static + Send + Sync,
@@ -149,6 +173,20 @@ where
}
}
impl<F, S, V, R> IntoPySetterFunc<(BorrowedParam<S>, V, R, VirtualMachine)> for F
where
F: Fn(&Py<S>, V, &VirtualMachine) -> R + 'static + Send + Sync,
S: PyPayload,
V: FromPySetterValue,
R: IntoPyNoResult,
{
fn set(&self, obj: PyObjectRef, value: PySetterValue, vm: &VirtualMachine) -> PyResult<()> {
let zelf = PyRef::<S>::try_from_object(vm, obj)?;
let value = V::from_setter_value(vm, value)?;
(self)(&zelf, value, vm).into_noresult()
}
}
impl<F, S, V, R> IntoPySetterFunc<(RefParam<S>, V, R, VirtualMachine)> for F
where
F: Fn(&S, V, &VirtualMachine) -> R + 'static + Send + Sync,
@@ -177,6 +215,20 @@ where
}
}
impl<F, S, V, R> IntoPySetterFunc<(BorrowedParam<S>, V, R)> for F
where
F: Fn(&Py<S>, V) -> R + 'static + Send + Sync,
S: PyPayload,
V: FromPySetterValue,
R: IntoPyNoResult,
{
fn set(&self, obj: PyObjectRef, value: PySetterValue, vm: &VirtualMachine) -> PyResult<()> {
let zelf = PyRef::<S>::try_from_object(vm, obj)?;
let value = V::from_setter_value(vm, value)?;
(self)(&zelf, value).into_noresult()
}
}
impl<F, S, V, R> IntoPySetterFunc<(RefParam<S>, V, R)> for F
where
F: Fn(&S, V) -> R + 'static + Send + Sync,

View File

@@ -13,7 +13,8 @@ pub use argument::{
};
pub use arithmetic::{PyArithmeticValue, PyComparisonValue};
pub use buffer::{ArgAsciiBuffer, ArgBytesLike, ArgMemoryBuffer, ArgStrOrBytesLike};
pub use builtin::{IntoPyNativeFunc, OwnedParam, PyNativeFunc, RefParam};
pub(self) use builtin::{BorrowedParam, OwnedParam, RefParam};
pub use builtin::{IntoPyNativeFunc, PyNativeFunc};
pub use either::Either;
pub use getset::PySetterValue;
pub(super) use getset::{IntoPyGetterFunc, IntoPySetterFunc, PyGetterFunc, PySetterFunc};