use crate::{imp::implements, Deserializer, NonTrivialObject, Serializer};
use std::io::Result;
pub trait PlainOldData: NonTrivialObject {}
mod private {
pub trait Sealed {}
}
pub trait Object: private::Sealed {
fn serialize_self(&self, s: &mut Serializer);
fn serialize_slice(elements: &[Self], s: &mut Serializer)
where
Self: Sized;
unsafe fn deserialize_self(d: &mut Deserializer) -> Result<Self>
where
Self: Sized;
#[doc(hidden)]
unsafe fn deserialize_on_heap(d: &mut Deserializer) -> Result<*mut ()>
where
Self: Sized;
#[doc(hidden)]
#[cfg(feature = "nightly")]
unsafe fn deserialize_on_heap_ptr(self: *const Self, d: &mut Deserializer) -> Result<*mut ()>;
#[doc(hidden)]
#[cfg(not(feature = "nightly"))]
fn deserialize_on_heap_get(&self) -> unsafe fn(&mut Deserializer) -> Result<*mut ()>;
}
impl<T: NonTrivialObject> private::Sealed for T {}
impl<T: NonTrivialObject> Object for T {
fn serialize_self(&self, s: &mut Serializer) {
if implements!(T: PlainOldData) {
s.write(unsafe {
std::slice::from_raw_parts(self as *const T as *const u8, std::mem::size_of::<T>())
});
} else {
self.serialize_self_non_trivial(s);
}
}
fn serialize_slice(elements: &[Self], s: &mut Serializer)
where
Self: Sized,
{
if implements!(T: PlainOldData) {
s.write(unsafe {
std::slice::from_raw_parts(
elements.as_ptr() as *const u8,
std::mem::size_of_val(elements),
)
});
} else {
for element in elements {
element.serialize_self_non_trivial(s)
}
}
}
unsafe fn deserialize_self(d: &mut Deserializer) -> Result<Self>
where
Self: Sized,
{
if implements!(T: PlainOldData) {
let mut val = std::mem::MaybeUninit::<T>::uninit();
d.read(std::slice::from_raw_parts_mut(
val.as_mut_ptr() as *mut u8,
std::mem::size_of::<T>(),
));
Ok(val.assume_init())
} else {
T::deserialize_self_non_trivial(d)
}
}
unsafe fn deserialize_on_heap(d: &mut Deserializer) -> Result<*mut ()>
where
Self: Sized,
{
Ok(Box::into_raw(Box::new(Self::deserialize_self(d)?)) as *mut ())
}
#[cfg(feature = "nightly")]
unsafe fn deserialize_on_heap_ptr(self: *const T, d: &mut Deserializer) -> Result<*mut ()> {
Self::deserialize_on_heap(d)
}
#[cfg(not(feature = "nightly"))]
fn deserialize_on_heap_get(&self) -> unsafe fn(&mut Deserializer) -> Result<*mut ()> {
Self::deserialize_on_heap
}
}