flat_message 0.2.1

Zero-copy, schema-less serialization and deserialization fast library for Rust.
Documentation
use super::{SerDe, SerDeSlice, SerDeVec, SerDeVecType};
use crate::size;
use crate::common::data_format::DataFormat;

unsafe impl<'a, const N: usize> SerDe<'a> for [u8; N] {
    const DATA_FORMAT: DataFormat = DataFormat::FixArray;

    unsafe fn from_buffer_unchecked(buf: &'a [u8], pos: usize) -> Self
    where
        Self: Sized,
    {
        let p = buf.as_ptr();
        let (_, slen) = size::read_unchecked(p, pos, size::Format::U8withExtension);
        let ptr = buf.as_ptr().add(pos + slen) as *const [u8; N];
        unsafe { *ptr }
    }

    fn from_buffer(buf: &'a [u8], pos: usize) -> Option<Self>
    where
        Self: Sized,
    {
        let (count, slen) =
            unsafe { size::read(buf.as_ptr(), pos, buf.len(), size::Format::U8withExtension)? };
        if count != N {
            None
        } else {
            unsafe {
                let ptr = buf.as_ptr().add(pos + slen) as *const [u8; N];
                Some(*ptr)
            }
        }
    }

    unsafe fn write(obj: &Self, p: *mut u8, pos: usize) -> usize {
        unsafe {
            let slen = size::write(p, pos, N as u32, size::Format::U8withExtension);
            std::ptr::copy_nonoverlapping(obj.as_ptr(), p.add(pos + slen), obj.len());
            pos + slen + N
        }
    }

    fn size(_: &Self) -> usize {
        crate::size::len(N as u32, crate::size::Format::U8withExtension) + N
    }
}

unsafe impl<'a, const N: usize> SerDeSlice<'a> for [u8; N] {
    const DATA_FORMAT: DataFormat = DataFormat::FixArray;
    #[inline(always)]
    unsafe fn from_buffer_unchecked(buf: &[u8], pos: usize) -> &'a [Self] {
        let (_, l1) = size::read_unchecked(buf.as_ptr(), pos, size::Format::U8withExtension);
        let (c, l2) = size::read_unchecked(buf.as_ptr(), pos + l1, size::Format::U8withExtension);
        unsafe { std::slice::from_raw_parts(buf.as_ptr().add(pos + l1 + l2) as *const [u8; N], c) }
    }
    #[inline(always)]
    fn from_buffer(buf: &'a [u8], pos: usize) -> Option<&'a [Self]> {
        let (count, slen1) =
            unsafe { size::read(buf.as_ptr(), pos, buf.len(), size::Format::U8withExtension)? };
        if count != N {
            return None;
        }
        let (count, slen2) = unsafe { size::read(
            buf.as_ptr(),
            pos + slen1,
            buf.len(),
            size::Format::U8withExtension,
        )? };
        let end = pos + count * N + slen1 + slen2;
        if end > buf.len() {
            None
        } else {
            Some(unsafe {
                std::slice::from_raw_parts(
                    buf.as_ptr().add(pos + slen1 + slen2) as *const [u8; N],
                    count,
                )
            })
        }
    }
    #[inline(always)]
    unsafe fn write(obj: &[Self], p: *mut u8, pos: usize) -> usize {
        unsafe {
            let slen1 = size::write(p, pos, N as u32, size::Format::U8withExtension);
            let slen2 = size::write(
                p,
                pos + slen1,
                obj.len() as u32,
                size::Format::U8withExtension,
            );
            std::ptr::copy_nonoverlapping(
                obj.as_ptr() as *const u8,
                p.add(pos + slen1 + slen2),
                obj.len() * N,
            );
            pos + slen1 + slen2 + obj.len() * N
        }
    }
    #[inline(always)]
    fn size(obj: &[Self]) -> usize {
        obj.len() * N
            + crate::size::len(N as u32, crate::size::Format::U8withExtension)
            + crate::size::len(obj.len() as u32, crate::size::Format::U8withExtension)
    }
}

unsafe impl<'a, const N: usize, TVecType: SerDeVecType<[u8; N]>> SerDeVec<'a, TVecType> for [u8; N] {
    const DATA_FORMAT: DataFormat = DataFormat::FixArray;
    #[inline(always)]
    unsafe fn from_buffer_unchecked(buf: &[u8], pos: usize) -> TVecType {
        let res: &[[u8; N]] = SerDeSlice::from_buffer_unchecked(buf, pos);
        TVecType::from_slice(res)
    }
    #[inline(always)]
    fn from_buffer(buf: &[u8], pos: usize) -> Option<TVecType> {
        let res: &[[u8; N]] = SerDeSlice::from_buffer(buf, pos)?;
        Some(TVecType::from_slice(res))
    }
    #[inline(always)]
    unsafe fn write(obj: &TVecType, p: *mut u8, pos: usize) -> usize {
        SerDeSlice::write(obj.as_slice(), p, pos)
    }
    #[inline(always)]
    fn size(obj: &TVecType) -> usize {
        SerDeSlice::size(obj.as_slice())
    }
}

unsafe impl<'a, const N: usize> SerDe<'a> for &'a [u8; N] {
    const DATA_FORMAT: DataFormat = DataFormat::FixArray;

    unsafe fn from_buffer_unchecked(buf: &'a [u8], pos: usize) -> Self
    where
        Self: Sized,
    {
        let p = buf.as_ptr();
        let (_, slen) = size::read_unchecked(p, pos, size::Format::U8withExtension);
        let ptr = buf.as_ptr().add(pos + slen) as *const [u8; N];
        unsafe { &*ptr }
    }

    fn from_buffer(buf: &'a [u8], pos: usize) -> Option<Self>
    where
        Self: Sized,
    {
        let (count, slen) =
            unsafe { size::read(buf.as_ptr(), pos, buf.len(), size::Format::U8withExtension)? } ;
        if count != N {
            None
        } else {
            unsafe {
                let ptr = buf.as_ptr().add(pos + slen) as *const [u8; N];
                Some(&*ptr )
            }
        }
    }

    unsafe fn write(obj: &Self, p: *mut u8, pos: usize) -> usize {
        unsafe {
            let slen = size::write(p, pos, N as u32, size::Format::U8withExtension);
            std::ptr::copy_nonoverlapping(obj.as_ptr(), p.add(pos + slen), obj.len());
            pos + slen + N
        }
    }

    fn size(_: &Self) -> usize {
        crate::size::len(N as u32, crate::size::Format::U8withExtension) + N
    }
}