use std::{any::TypeId, marker::PhantomData, ptr::NonNull};
use crate::{data_holder::DataHolder, DataReference};
pub struct DataReferenceGeneric {
ptr: NonNull<u8>,
type_id: TypeId,
inner_type_id: TypeId,
drop_fn: &'static dyn Fn(NonNull<u8>),
}
impl DataReferenceGeneric {
pub fn type_id(&self) -> TypeId {
self.type_id
}
pub fn inner_type_id(&self) -> TypeId {
self.inner_type_id
}
pub fn to_typed<T: 'static>(&self) -> Option<DataReference<T>> {
if TypeId::of::<DataReference<T>>() == self.type_id {
let tmp = DataReference::<T> {
ptr: self.ptr.cast::<DataHolder<T>>(),
phantom: PhantomData,
};
tmp.increment_refcount();
Some(tmp)
} else {
None
}
}
}
unsafe impl Send for DataReferenceGeneric {}
unsafe impl Sync for DataReferenceGeneric {}
impl<T: 'static> From<DataReference<T>> for DataReferenceGeneric {
fn from(source: DataReference<T>) -> Self {
source.increment_refcount();
Self {
ptr: source.ptr.cast::<u8>(),
type_id: TypeId::of::<DataReference<T>>(),
inner_type_id: TypeId::of::<T>(),
drop_fn: &DataReference::<T>::drop_impl,
}
}
}
impl Drop for DataReferenceGeneric {
fn drop(&mut self) {
(self.drop_fn)(self.ptr.cast::<u8>());
}
}