use crate::{DeserInner, deser::DeserType, ser::SerInner};
use bitflags::bitflags;
use core::{fmt, mem::size_of};
#[cfg(not(feature = "std"))]
use alloc::boxed::Box;
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Flags: u32 {
const TRANSPARENT_HUGE_PAGES = 1 << 0;
const SEQUENTIAL = 1 << 1;
const RANDOM_ACCESS = 1 << 2;
}
}
impl core::default::Default for Flags {
fn default() -> Self {
Flags::empty()
}
}
impl Flags {
#[cfg(feature = "mmap")]
pub(crate) fn mmap_flags(&self) -> mmap_rs::MmapFlags {
let mut flags: mmap_rs::MmapFlags = mmap_rs::MmapFlags::empty();
if self.contains(Self::SEQUENTIAL) {
flags |= mmap_rs::MmapFlags::SEQUENTIAL;
}
if self.contains(Self::RANDOM_ACCESS) {
flags |= mmap_rs::MmapFlags::RANDOM_ACCESS;
}
if self.contains(Self::TRANSPARENT_HUGE_PAGES) {
flags |= mmap_rs::MmapFlags::TRANSPARENT_HUGE_PAGES;
}
flags
}
}
pub type MemoryAlignment = crate::Aligned64;
#[derive(Debug)]
#[cfg_attr(feature = "mem_dbg", derive(mem_dbg::MemDbg, mem_dbg::MemSize))]
pub enum MemBackend {
None,
Memory(Box<[MemoryAlignment]>),
#[cfg(feature = "mmap")]
Mmap(mmap_rs::Mmap),
}
impl MemBackend {
pub fn as_ref(&self) -> Option<&[u8]> {
match self {
MemBackend::None => None,
MemBackend::Memory(mem) => Some(unsafe {
core::slice::from_raw_parts(
mem.as_ptr() as *const MemoryAlignment as *const u8,
mem.len() * size_of::<MemoryAlignment>(),
)
}),
#[cfg(feature = "mmap")]
MemBackend::Mmap(mmap) => Some(mmap),
}
}
}
#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "mem_dbg", derive(mem_dbg::MemDbg, mem_dbg::MemSize))]
#[repr(transparent)]
pub struct Owned<T>(T);
pub type MemOwned<T> = MemCase<Owned<T>>;
impl<T> DeserInner for Owned<T> {
type DeserType<'a> = T;
#[inline(always)]
fn __check_covariance<'__long: '__short, '__short>(
proof: super::CovariantProof<Self::DeserType<'__long>>,
) -> super::CovariantProof<Self::DeserType<'__short>> {
proof
}
unsafe fn _deser_full_inner(_backend: &mut impl super::ReadWithPos) -> super::Result<Self> {
unimplemented!();
}
unsafe fn _deser_eps_inner<'a>(
_backend: &mut super::SliceWithPos<'a>,
) -> super::Result<Self::DeserType<'a>> {
unimplemented!();
}
}
impl<T> SerInner for Owned<T> {
type SerType = T;
const IS_ZERO_COPY: bool = false;
unsafe fn _ser_inner(
&self,
_backend: &mut impl crate::ser::WriteWithNames,
) -> crate::ser::Result<()> {
unimplemented!();
}
}
#[cfg_attr(feature = "mem_dbg", derive(mem_dbg::MemDbg, mem_dbg::MemSize))]
pub struct MemCase<S: DeserInner>(pub(crate) DeserType<'static, S>, pub(crate) MemBackend);
impl<S: DeserInner> fmt::Debug for MemCase<S>
where
DeserType<'static, S>: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("MemCase")
.field(&self.0)
.field(&self.1)
.finish()
}
}
impl<T> From<T> for MemCase<Owned<T>> {
fn from(t: T) -> Self {
<MemOwned<T>>::encase(t)
}
}
impl<S: DeserInner> MemCase<S> {
pub const fn encase<T>(s: T) -> MemOwned<T> {
MemCase(s, MemBackend::None)
}
pub fn uncase<'a>(&'a self) -> &'a DeserType<'a, S> {
super::__check_type_covariance::<S>();
unsafe { core::mem::transmute::<&'a DeserType<'static, S>, &'a DeserType<'a, S>>(&self.0) }
}
pub unsafe fn uncase_static(&self) -> &DeserType<'static, S> {
&self.0
}
}
unsafe impl<S: DeserInner> Send for MemCase<S> where DeserType<'static, S>: Send {}
unsafe impl<S: DeserInner> Sync for MemCase<S> where DeserType<'static, S>: Sync {}
impl<A, S: DeserInner> AsRef<A> for MemCase<S>
where
for<'a> DeserType<'a, S>: AsRef<A>,
{
fn as_ref(&self) -> &A {
self.uncase().as_ref()
}
}
impl<A, T: AsRef<A>> AsRef<A> for Owned<T> {
fn as_ref(&self) -> &A {
self.0.as_ref()
}
}
impl<A: ?Sized, S: DeserInner> core::ops::Deref for MemCase<S>
where
for<'a> DeserType<'a, S>: core::ops::Deref<Target = A>,
{
type Target = <DeserType<'static, S> as core::ops::Deref>::Target;
fn deref(&self) -> &Self::Target {
self.uncase().deref()
}
}
impl<S: DeserInner> PartialEq<MemCase<S>> for MemCase<S>
where
for<'a, 'b> DeserType<'a, S>: PartialEq<DeserType<'b, S>>,
{
fn eq(&self, other: &MemCase<S>) -> bool {
self.uncase().eq(other.uncase())
}
}
impl<S: DeserInner> Eq for MemCase<S>
where
for<'a, 'b> DeserType<'a, S>: PartialEq<DeserType<'b, S>>,
for<'a> DeserType<'a, S>: Eq,
{
}