use crate::class::{
basic::PyObjectMethods, descr::PyDescrMethods, gc::PyGCMethods, iter::PyIterMethods,
};
use crate::ffi::{
PyAsyncMethods, PyBufferProcs, PyMappingMethods, PyNumberMethods, PySequenceMethods,
};
use std::{
ptr::{self, NonNull},
sync::atomic::{AtomicPtr, Ordering},
};
pub trait PyProtoMethods {
fn async_methods() -> Option<NonNull<PyAsyncMethods>> {
None
}
fn basic_methods() -> Option<NonNull<PyObjectMethods>> {
None
}
fn buffer_methods() -> Option<NonNull<PyBufferProcs>> {
None
}
fn descr_methods() -> Option<NonNull<PyDescrMethods>> {
None
}
fn gc_methods() -> Option<NonNull<PyGCMethods>> {
None
}
fn mapping_methods() -> Option<NonNull<PyMappingMethods>> {
None
}
fn number_methods() -> Option<NonNull<PyNumberMethods>> {
None
}
fn iter_methods() -> Option<NonNull<PyIterMethods>> {
None
}
fn sequence_methods() -> Option<NonNull<PySequenceMethods>> {
None
}
}
#[doc(hidden)]
pub trait HasProtoRegistry: Sized + 'static {
fn registry() -> &'static PyProtoRegistry;
}
impl<T: HasProtoRegistry> PyProtoMethods for T {
fn async_methods() -> Option<NonNull<PyAsyncMethods>> {
NonNull::new(Self::registry().async_methods.load(Ordering::Relaxed))
}
fn basic_methods() -> Option<NonNull<PyObjectMethods>> {
NonNull::new(Self::registry().basic_methods.load(Ordering::Relaxed))
}
fn buffer_methods() -> Option<NonNull<PyBufferProcs>> {
NonNull::new(Self::registry().buffer_methods.load(Ordering::Relaxed))
}
fn descr_methods() -> Option<NonNull<PyDescrMethods>> {
NonNull::new(Self::registry().descr_methods.load(Ordering::Relaxed))
}
fn gc_methods() -> Option<NonNull<PyGCMethods>> {
NonNull::new(Self::registry().gc_methods.load(Ordering::Relaxed))
}
fn mapping_methods() -> Option<NonNull<PyMappingMethods>> {
NonNull::new(Self::registry().mapping_methods.load(Ordering::Relaxed))
}
fn number_methods() -> Option<NonNull<PyNumberMethods>> {
NonNull::new(Self::registry().number_methods.load(Ordering::Relaxed))
}
fn iter_methods() -> Option<NonNull<PyIterMethods>> {
NonNull::new(Self::registry().iter_methods.load(Ordering::Relaxed))
}
fn sequence_methods() -> Option<NonNull<PySequenceMethods>> {
NonNull::new(Self::registry().sequence_methods.load(Ordering::Relaxed))
}
}
#[doc(hidden)]
pub struct PyProtoRegistry {
async_methods: AtomicPtr<PyAsyncMethods>,
basic_methods: AtomicPtr<PyObjectMethods>,
buffer_methods: AtomicPtr<PyBufferProcs>,
descr_methods: AtomicPtr<PyDescrMethods>,
gc_methods: AtomicPtr<PyGCMethods>,
mapping_methods: AtomicPtr<PyMappingMethods>,
number_methods: AtomicPtr<PyNumberMethods>,
iter_methods: AtomicPtr<PyIterMethods>,
sequence_methods: AtomicPtr<PySequenceMethods>,
}
impl PyProtoRegistry {
pub const fn new() -> Self {
PyProtoRegistry {
async_methods: AtomicPtr::new(ptr::null_mut()),
basic_methods: AtomicPtr::new(ptr::null_mut()),
buffer_methods: AtomicPtr::new(ptr::null_mut()),
descr_methods: AtomicPtr::new(ptr::null_mut()),
gc_methods: AtomicPtr::new(ptr::null_mut()),
mapping_methods: AtomicPtr::new(ptr::null_mut()),
number_methods: AtomicPtr::new(ptr::null_mut()),
iter_methods: AtomicPtr::new(ptr::null_mut()),
sequence_methods: AtomicPtr::new(ptr::null_mut()),
}
}
pub fn set_async_methods(&self, methods: PyAsyncMethods) {
self.async_methods
.store(Box::into_raw(Box::new(methods)), Ordering::Relaxed)
}
pub fn set_basic_methods(&self, methods: PyObjectMethods) {
self.basic_methods
.store(Box::into_raw(Box::new(methods)), Ordering::Relaxed)
}
pub fn set_buffer_methods(&self, methods: PyBufferProcs) {
self.buffer_methods
.store(Box::into_raw(Box::new(methods)), Ordering::Relaxed)
}
pub fn set_descr_methods(&self, methods: PyDescrMethods) {
self.descr_methods
.store(Box::into_raw(Box::new(methods)), Ordering::Relaxed)
}
pub fn set_gc_methods(&self, methods: PyGCMethods) {
self.gc_methods
.store(Box::into_raw(Box::new(methods)), Ordering::Relaxed)
}
pub fn set_mapping_methods(&self, methods: PyMappingMethods) {
self.mapping_methods
.store(Box::into_raw(Box::new(methods)), Ordering::Relaxed)
}
pub fn set_number_methods(&self, methods: PyNumberMethods) {
self.number_methods
.store(Box::into_raw(Box::new(methods)), Ordering::Relaxed)
}
pub fn set_iter_methods(&self, methods: PyIterMethods) {
self.iter_methods
.store(Box::into_raw(Box::new(methods)), Ordering::Relaxed)
}
pub fn set_sequence_methods(&self, methods: PySequenceMethods) {
self.sequence_methods
.store(Box::into_raw(Box::new(methods)), Ordering::Relaxed)
}
}